Customizing error reports

In order to quickly reproduce and fix errors, it is often helpful to send additional application-specific diagnostic “metadata” to your Bugsnag dashboard to provide a rich context that is also available for searching and filtering.

You can also amend the events captured by Bugsnag to adjust the information shown on the dashboard and even choose not to send the event at all.

This documentation is for version 7 of the Bugsnag JavaScript notifier. If you are using older versions, we recommend upgrading to the latest release using our Upgrade guide. Documentation for the previous release can be found on our legacy pages.

Updating events using callbacks

If you’d like to add diagnostic data to reports, or adjust event data conditionally, you can use an onError callback, which will be run immediately after an error is captured or reported:

Bugsnag.start({
  onError: function (event) {
    // Amend event information
    event.errors[0].errorClass = 'com.example.BadClass'

    // Add additional diagnostic information
    event.addMetadata('account', {
      type: 'paid',
      betaAccess: true
    })
  }
})

The callback gives you access to the Event object, so you can inspect and modify the error event which is about to be sent to Bugsnag.

Adding and removing callbacks

We recommend adding callbacks through the onError configuration option to ensure that it is registered as soon as Bugsnag starts. However, the following methods are provided to allow callbacks to be added and removed whilst the application is running:

var cb = function (event) { /* ... */ };
Bugsnag.addOnError(cb);
// ...
Bugsnag.removeOnError(cb);

Discarding events

If you want to prevent an event from being sent to Bugsnag, you can return false within an onError. This would allow for users to opt out of sending error reports, for example:

Bugsnag.start({
  onError: function (event) {
    return !userHasOptedOut()
  }
})

If you’re using an asynchronous callback, to prevent an event from being sent you can asynchronously “return false” with resolve(false)/cb(null, false) depending on the style of function used.

Asynchronous onError callbacks

We recommend using the synchronous interface as shown above, but it is possible to provide an asynchronous onError callback using a Node-style error-first callback, a Promise or an async function.

Anything that can take a long time or cause subsequent errors should be discouraged – if this is a particularly catastrophic error then you want to avoid doing any work that might prevent the report from sending.

Bugsnag.start({
  onError: event =>
    new Promise((resolve, reject) => {
      // doing some asynchronous work, resolving when done
      resolve()
      // if an error happened, you can reject the promise but this error won't
      // prevent the event from being sent (or other callbacks from being run)
      reject(err)
      // to stop the event from being sent resolve with false
      resolve(false)
    })
  }
})
Bugsnag.start({
  onError: (event, cb) =>
    // doing some asynchronous work, calling cb(err, ignore?) when done
    cb(null)
    // if an error happens call cb(err) – this won't prevent
    // the event from being sent
    cb(err)
    // prevent event from sending
    cb(null, false)
  }
})
Bugsnag.start({
  onError: async event =>
    // doing some asynchronous work
    await somethingAsync()
    // you can explicitly return true, or just not return at all (implicitly returning undefined)
    return true
    // to stop the event from being sent return false
    return false
  }
})

Global metadata

If you have metadata that is applicable to all captured events, it can be set globally on the Bugsnag client and will be set on all subsequently generated events. To ensure that events contain metadata as soon as Bugsnag starts capturing events, add it to the metadata field on the configuration object.

The top-level key in the map is displayed as a tab in the Bugsnag dashboard:

Bugsnag.start({
  metadata: {
    company: {
      {
        name: 'Acme Co.',
        country: 'uk'
      }
    }
  }
})

Metadata can also be managed whilst your application is running using addMetadata and clearMetadata on the Bugsnag client:

Bugsnag.addMetadata('company', {
  name: 'Acme Co.',
  country: 'uk'
})
// ...
Bugsnag.clearMetadata('company');

Adding user data

Information about the user affected by errors can be added to events sent to your Bugsnag dashboard by setting the user ID, email and name in Configuration when Bugsnag starts:

Bugsnag.start({ 
  user: {
    id: '3',
    name: 'Bugs Nag',
    email: 'bugs.nag@bugsnag.com'
  }
})

In the browser, or in other environments where your process will only be serving a single user (such as a CLI app in Node.js), you can attach user data directly on the Bugsnag instance after Bugsnag has started (for example, when the user logs in). This will then be sent along with all subsequent errors.

Bugsnag.setUser('3', 'bugs.nag@bugsnag.com', 'Bugs Nag')

Alternatively, you can set the user for each event through an onError callback:

Bugsnag.start({
  onError: function (event) {
    event.setUser('3', 'bugs.nag@bugsnag.com', 'Bugs Nag')
  }
})

You can use metadata to add additional user information to the “user” section.

Setting context

Bugsnag uses the concept of “contexts” to help display and group your errors. The context represents what was happening in your application at the time an error occurs and is given high visual prominence in the dashboard.

By default, in the browser, Bugsnag sets the context for each event to window.location.pathname. If you would like to set this value manually, you can set it in Configuration when Bugsnag starts:

Bugsnag.start({ context: 'ctx-id-1234' })

The context can then be amended on the Bugsnag client as/when it changes for all subsequent events:

Bugsnag.setContext('User settings screen')

Alternatively, the context can be amended for each event using an onError callback:

Bugsnag.start({
  onError: function (event) {
    event.context = 'User settings screen'
  }
})

Preventing IP address collection

The client’s IP address is collected by default and used in both the user identifier and Request tab on the dashboard. This can be prevented by setting the collectUserIp: false option.

Note that by not collecting IPs, reports will all appear to come from the same user unless a user ID is specified. We strongly recommend that you supply a user ID so you can prioritize bugs by the number of users affected. Libraries such as Fingerprintjs can be used to create an anonymous, unique, but reproducible identifiers.

To prevent IP collection but set user IDs:

Bugsnag.start({
  collectUserIp: false,
  onError: function (event) {
    var userId = getMyUserIdentifier() // a custom user resolver
    event.setUser(userId)
  }
})

If the user ID value is known when configuring Bugsnag, you can set user right away:

Bugsnag.start({
  collectUserIp: false,
  user: { id: '1234' }
})

For more information on these top-level values, see the configuration options documentation for user and request.

The Event object

An Event object represents an error captured by Bugsnag and is available as a parameter on an onError callback. The following properties and methods are available for you to query and update the captured data:

addMetadata

Adds the specified key and value in the specified section, which is shown as a tab on the Bugsnag dashboard.

Data can be added key-by-key with a value that is a primitive type, map or array:

event.addMetadata('company', 'name', 'Acme Co.')

Alternatively a whole map of key-value pairs can be added for a section:

event.addMetadata('company', {
  name: "Acme Co.",
  country: "uk"
})

Metadata set on the event will be combined with global metadata set on the Bugsnag client, with properties on the Event taking precedence.

apiKey

The API key used for events sent to Bugsnag. Even though the API key is set when Bugsnag is initialized, you may choose to send certain events to a different Bugsnag project:

event.apiKey = 'YOUR-API-KEY'

app

Information set by the notifier about your application can be found in event.app:

property type description
releaseStage String The release stage set in Configuration
type String The application type set in Configuration
version String The version of the application set in Configuration

These values can be accessed and amended if necessary:

event.app.type = 'worker'

An array of breadcrumbs leading up to the event can be found in event.breadcrumbs[].

Each breadcrumb consists of the following:

property type description
type String The type of breadcrumb left - one of those enabled in Configuration
message String The description of the breadcrumb
metadata String Diagnostic data relating to the breadcrumb
timestamp String The timestamp that the breadcrumb was left

These values can be accessed and amended if necessary:

event.breadcrumbs[0].message = 'Left homepage'

clearMetadata

Removes all the data from the specified section or from a key in the section:

// Remove a metadata field
event.clearMetadata('company', 'name')
// or
event.clearMetadata('company')

context

The context represents what was happening in your application at the time an error occurs.

event.context = 'User settings screen'

See Setting context for more information.

device

Information set by the notifier about the device on which the event occurred can be found in event.device:

property type description
hostname String The local network name of the device or set in Configuration (Node.js only)
locale String The IETF language tag of the locale used
runtimeVersions Map A collection of names and their versions of the primary languages, frameworks or runtimes that the application is running on
time String The timestamp on the device when the event occurred
userAgent String The User Agent String reported by the web browser

These values can be accessed and amended if necessary:

event.device.locale = 'de-DE'

errors

Information extracted from the error that caused the event can be found in event.errors. This array contains at least one Error that represents the thrown object with subsequent elements representing errors that caused the preceding error.

A reference to the actual error object that caused the event is available through event.originalError.

An Error object contains the following information:

property type description
errorClass String The fully-qualified class name of the error
errorMessage String The message string from the error
stacktrace Stackframe[] A representation of the stacktrace
type String The type of error based on the originating platform (intended for internal use only)
event.errors[0].errorClass = 'MyError'

In an Error object, the stacktrace is an array of the following Stackframe objects:

property type description
code Object When possible (in Node or an inline script in the browser), the notifier will extract the surrounding code and populate this property.
columnNumber Number The column number within the source file this stackframe refers to. This can be undefined when the column number is not known.
file String The location of the executing file. This can be a file path, URL or a value such as 'global code'. If the executing file is an inline script on a web page, this will be the URL of the page it was loaded on.
inProject Boolean In Node, stack frames from outside the project root or inside node_modules will be marked as inProject: false. In the browser and in Expo, this is always set to undefined by default. You can update this property to indicate when stackframes are known to be outside of your project in order to improve grouping and stacktrace readability. See the example below.
lineNumber Number The line number within the source file this stackframe refers to.
method String The name of the method that was being executed, if available.

These values can be accessed and amended if necessary:

// Sets the `inProject` property to `false` for anything with "vendor" in the path
event.errors[0].stacktrace.forEach(function (frame) {
  var inProject = !/\/vendor\//.test(frame.file)
  // If you set one stackframe.inProject you should set them all
  frame.inProject = inProject
})

If your code is minified, source maps will not have been applied at this point, and so your stackframes will have locations and methods from minified code.

getMetadata

Returns a map of data in the specified section and optionally key:

var company = event.getMetadata('company')
// or
var companyName = event.getMetadata('company', 'name')

getUser

Returns the current user information:

var userId = event.getUser().id
var userEmail = event.getUser().email
var userName = event.getUser().name

groupingHash

Set the grouping hash of the event to override the default grouping on the dashboard. All events with the same grouping hash will be grouped together into one error. This is an advanced usage of the library and mis-using it will cause your events not to group properly in your dashboard.

event.groupingHash = event.errors[0].errorClass

By default, events are grouped by the statement in your code that raised the error. We try to use the surrounding code to identify the statement, but if that’s not possible we fall back to using line number and filename as an approximation.

request

Information automatically set by the notifier about the web page on which the event occurred:

property type description
body String The body of the request (Node.js only)
clientIp String The IP address of the user making the request, if enabled in Configuration
connection Map Details of the connection used to transmit the request (Node.js only)
headers Map The headers of the request (Node.js only)
httpMethod String The HTTP method of the request (Node.js only)
httpVersion String The HTTP version of the request (Node.js only)
params String The parameters in the route of the request (Node.js only)
path String The path of the requested resource (Node.js only)
query String The querystring of the request (Node.js only)
referer String The referer of the request (Node.js only)
url String The URL of the request

These values can be accessed and amended if necessary:

event.request.url = 'https://domain.com/page'

originalError

The error object that caused the event in your application.

Manipulating event.originalError does not affect the error information reported to the Bugsnag dashboard. Use event.errors to access and amend the representation of the error that will be sent.

if (event.originalError instanceof Error) // ...

setUser

Sets the current user information.

event.setUser('3', 'bugs.nag@bugsnag.com', 'Bugs Nag')

null can be used as a parameter value to clear the user attribute.

severity

The seriousness of the error, selected from the options info, warning and error, listed in order of increasing severity:

event.severity = 'warning'

unhandled

Whether the error was detected automatically by Bugsnag (true), or reported manually via Bugsnag.notify (false).

if (event.unhandled) // ...

This property is readonly: changing the value in a callback will not affect the value sent to Bugsnag.