Last updatedApr 16, 2020

Rate this page:

Debugging

Debugging is the process of finding and fixing problems in your code. This page describes how to debug Forge apps, including:

  • How to diagnose problems using debugging features of the Forge platform, such as logging and tunneling.
  • How to identify different types of problems, such as Forge UI errors.

Note that this page does not cover observability, which is an overview of how well an app is working (for example, monitoring performance).

Invoking functions

To invoke a function that you want to debug, such as a scheduled trigger or product trigger for an unusual event, add consider configuring a web trigger for the function. See the Add scheduled trigger guide as an example.

Diagnosing problems

Forge provides a number of features to help you diagnose problems with your app, such as tunneling and logging. The following section describes these features and how to use them.

Logging

Logging messages to the console is a common process for debugging code. Forge supports logging via the forge logs CLI command, which shows the logs for your deployed app.

The forge logs command works like this:

  1. Insert console.log() statements into your app’s code. For example, you may want to inspect values of variables as the code executes.
    Tip: If you want to pretty print a JSON object, use a statement like console.log(JSON.stringify(jsonObject, null, 2)).
  2. Deploy and run your app.
  3. In the CLI, run forge logs.

The output of your logging statements will be shown in the CLI. For example:

1
INFO  2020-01-22T06:36:33.843Z f93rfad-1234-d920-a98r-9aendas93 Number of comments on this page: 2

Each logging statement has the following structure:

  • Logging level, for example, INFO, WARN, ERROR, etc.
  • Timestamp in UTC format in "verbose mode”, that is, a longer format.
  • Invocation ID
  • Logging message

Options for the forge logs command

You can use a number of options with the forge logs command to modify the data returned:

forge logs --verbose: Adding the verbose option shows log statements with their attached metadata. Nested JSON objects are shown as a string. For example:

1
2
3
INFO  2020-01-22T06:36:33.843Z 194b0adb-7362-4f0d-8fc9-6ee950bea769 Number of comments on this page: 2
    App version: 1001000
    Function name: main

forge logs --grouped: Adding the grouped option shows log statements grouped by Invocation ID. For example:

1
2
3
4
5
invocation: 194b0adb-7362-4f0d-8fc9-6ee950bea769
INFO  06:36:33.843Z Number of comments on this page: 2

invocation: b3d763d0-2ebd-40fe-88a4-79e8170f8c48
INFO  01:09:26.988Z Number of comments on this page: 0

forge logs --verbose --grouped: Adding both the verbose and grouped options shows log statements grouped by Invocation ID with the attached metadata. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
┌─────────────────────────────────────────────────────┐
│ App version    1001000                              │
│ Invocation ID  194b0adb-7362-4f0d-8fc9-6ee950bea769 │
│ Function name  main                                 │
└─────────────────────────────────────────────────────┘

INFO  2020-01-22T06:36:33.843Z 194b0adb-7362-4f0d-8fc9-6ee950bea769 Number of comments on this page: 2
    App version: 1001000
    Function name: main

┌─────────────────────────────────────────────────────┐
│ App version    6                                    │
│ Invocation ID  b3d763d0-2ebd-40fe-88a4-79e8170f8c48 │
│ Function name  main                                 │
└─────────────────────────────────────────────────────┘

INFO  2020-02-21T01:09:26.988Z b3d763d0-2ebd-40fe-88a4-79e8170f8c48 Number of comments on this page: 0
    App version: 6
    Function name: main

Tunneling

Tunneling runs your app code locally on your machine via the Forge CLI. This helps you debug your app in two ways:

  • Real-time logging for your local app: Insert console.log() statements in your code and see the output in the Forge CLI as the code executes.
    Tip: If you want to pretty print a JSON object, use a statement like console.log(JSON.stringify(jsonObject, null, 2)).
  • Fast turnaround for changes: The tunnel watches for code changes and rebuilds your app. You don’t need to deploy your app after every change, which means that you can test fixes faster.

To start a tunnel for your app, run the following command in your CLI:

1
forge tunnel

You will see output similar to this:

1
2
3
4
5
6
7
Starting tunneling for the development environment. Your local app will receive requests from everywhere 
the app in the development environment is installed.
Press Ctrl+C to cancel.

Listening for requests on local port 12345...
Bundling succeeded.
App code reloaded.

Messages logged to the console will look similar to this:

1
INFO  17:34:04.955 Count of objects in test array: 0

If you use tunneling during development, be aware of the following:

  • Any logging that happens while you are tunneling won’t show in forge logs. This is because your app code runs locally while tunneling. forge logs only shows information for your deployed app, not locally running code.
  • If you make changes to the app manifest, you must deploy the app with the latest manifest for the tunnel to pick up the changes.
  • Environment variables must be set locally, as the tunnel can't access the values set in other environments.
  • Tunneling only displays output from your usage of the app, that is, your requests.

Identifying problems

Forge has error handling for common app issues, such as not implementing Forge UI components in the correct order. This helps you identify bugs, which you can investigate using tools such as logging. The following section describes the types of errors that are captured and where to view them.

Forge UI errors

Component composition errors: Returned if a component is not implemented in the correct order, according to the hierarchy for Forge UI components. For example, a TextField must always be implemented in a Form. These errors are shown in the app UI. For example: Forge UI component composition error example

Component import errors: Returned if a component is used in your app's code but not imported. For example, your app's code contains <Text content="hello" /> but it is missing import { Text } from "@forge/ui". These errors are shown in the app UI and Forge logs and tunnel. For example: Forge UI missing component error example Error shown in the logs:

1
INFO  2020-02-25T23:58:58.705Z 3d462797-22f5-438e-8be2-a18ab379b35b undefined {"name":"ReferenceError","message":"Text is not defined","stack":"ReferenceError: Text is not defined\n    at Object.App [as type] (index.js:23753:24)\n    at index.js:23382:26\n    at async index.js:23570:25"}

Error shown in the tunnel:

1
2
3
4
INFO  14:57:13.286 Number of comments on this page: 0
INFO  14:57:13.287 {"name":"ReferenceError","message":"Text is not defined","stack":"ReferenceError: Text is not defined\n    at Object.App [as type] (webpack-internal:///73:12883:24)\n    at eval (webpack-internal:///73:12512:26)\n    at async eval (webpack-internal:///73:12700:25)"}
ERROR 14:57:13.290 {"name":"FUNCTION_ERR"}
Error: Text is not defined

General coding errors

JSX errors: Returned for general JSX compile-time errors. For example, syntax errors. These errors are shown in the Forge CLI during deployment or while tunneling. A stack trace is also shown. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
✕ Deploying hello-world-app to development...
ℹ Packaging app files
Error: Bundling failed: ./src/index.jsx
Module build failed (from /usr/local/lib/node_modules/@forge/cli/node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/alui/src/forge/hello-world-app/src/index.jsx: Unexpected token (19:6)
  17 |     <Fragment>
  18 |       <Text content={`Number of comments on this page: ${comments.length}`}
> 19 |       <Image
     |       ^
  20 |         src="https://media.giphy.com/media/jUwpNzg9IcyrK/source.gif"
  21 |         alt="homer"
  22 |       />
    at Object.raise (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:7017:17)
    at Object.unexpected (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:8395:16)
    at Object.jsxParseIdentifier (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:3894:12)
    at Object.jsxParseNamespacedName (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:3904:23)
    at Object.jsxParseAttribute (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:3988:22)
    at Object.jsxParseOpeningElementAfterName (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:4009:28)
    at Object.jsxParseOpeningElementAfterName (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:6459:18)
    at Object.jsxParseOpeningElementAt (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:4002:17)
    at Object.jsxParseElementAt (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:4034:33)
    at Object.jsxParseElementAt (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:4050:32)
    at Object.jsxParseElement (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:4108:17)
    at Object.parseExprAtom (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:4115:19)
    at Object.parseExprSubscripts (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:9259:23)
    at Object.parseMaybeUnary (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:9239:21)
    at Object.parseMaybeUnary (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:6269:20)
    at Object.parseExprOps (/usr/local/lib/node_modules/@forge/cli/node_modules/@babel/parser/lib/index.js:9109:23)

Runtime errors: Returned for general runtime errors. For example, calling a method that does not exist or is not a method. These errors are shown in the app UI. A stack trace is included with the error message. For example: Runtime error example

  • Getting started: The getting started tutorials demonstrate how forge logs and forge tunnel are used in building an example app in Jira and Confluence.
  • Forge UI components: This reference page describes the available Forge UI components.

Rate this page: