Customizing error reports

In order to quickly reproduce and fix errors, it is often helpful to send additional application-specific diagnostic data to your BugSnag dashboard to provide 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.

Updating events using callbacks

If you’d like to add diagnostic data to events, or adjust event data conditionally, you can use an OnErrorCallback, which will be run before each error event is sent.

Callbacks are usually configured on the Bugsnag client (for example during application startup) and give you access to a BugsnagEvent object that you can inspect and modify before it is delivered to BugSnag.

bugsnag.addOnError((event) -> {
    event.addMetadata("account", "name", "Acme Co.");
    event.addMetadata("account", "paying_customer", true);

    // Return false to prevent this event from being sent
    return true;
});

Or without using lambda syntax:

bugsnag.addOnError(new OnErrorCallback() {
    @Override
    public boolean onError(BugsnagEvent event) {
        event.addMetadata("account", "name", "Acme Co.");
        event.addMetadata("account", "paying_customer", true);

        // Return false to prevent this event from being sent
        return true;
    }
});

The BugsnagEvent methods support chaining, for example:

event.setSeverity(Severity.ERROR)
     .setContext("Processing");

BugSnag will automatically add diagnostic information on the JVM runtime, O/S, and locale. For javax.servlet API apps (including Spring MVC), information about the request will be collected automatically.

Discarding events

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

bugsnag.addOnError((event) -> {
    return !userHasOptedOut();
});

You can also discard events for specific exception types:

bugsnag.addOnError((event) -> {
    if (event.getExceptionName().equals("com.example.IgnoredException")) {
        return false;
    }
    return true;
});

Alternatively, you can use discardClasses to prevent specific exception types from being reported at all.

Global metadata

If you have metadata that is applicable to all captured events, it can be set globally using addOnError and will be attached to all subsequently generated events:

bugsnag.addOnError((event) -> {
    event.addMetadata("company", "name", "Acme Co.");
    return true;
});

Thread metadata

If you have data that is relevant to the work a thread is doing (such as the current message being processed), it is possible to add metadata to any errors reported on that thread:

Bugsnag.addThreadMetadata("message", "id", "12345");

bugsnag.notify(new RuntimeException("Message ID will be included here"), Severity.ERROR);
bugsnag.notify(new RuntimeException("and also here"), Severity.INFO);

If your threads are reused to run multiple tasks, such as in a ThreadPoolExecutor, then you should ensure that metadata is cleared at the end of each task. Thread metadata will be automatically cleared at the end of an HTTP request when using the Servlet API.

Bugsnag.clearThreadMetadata(); // clear all metadata for the current thread

You can also remove a particular section from the thread metadata, or a particular key within a section:

Bugsnag.clearThreadMetadata("sectionToClear"); // clear thread metadata section
Bugsnag.clearThreadMetadata("sectionToClear", "keyToClear"); // clear thread metadata key

Thread metadata uses ThreadLocal storage, so it is only available on the thread where it was set. Each thread has its own separate metadata storage.

Adding user data

Information about the user affected by errors can be set using an OnErrorCallback:

bugsnag.addOnError((event) -> {
    event.setUser("12345", "user@example.com", "User Name");
    return true;
});

User details can also be set individually:

bugsnag.addOnError((event) -> {
    event.setUserId("12345");
    event.setUserEmail("user@example.com");
    event.setUserName("User Name");
    return true;
});

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, the context is set as the request method and URI for the current HTTP request if using the Servlet API. The context can be amended for each event using an OnErrorCallback:

bugsnag.addOnError((event) -> {
    event.setContext("PaymentProcessing");
    return true;
});

Feature flags

Monitor errors as you roll out features or run experiments and A/B tests by declaring your feature flag and experiment usage. Feature flags can be added at the client level or per-event:

// Add feature flags at the client level (attached to all subsequent events)
bugsnag.addFeatureFlag("Checkout button color", "Blue");
bugsnag.addFeatureFlag("New checkout flow");

// Add feature flags to a specific event
bugsnag.addOnError((event) -> {
    event.addFeatureFlag("Checkout button color", "Blue");
    event.addFeatureFlag("New checkout flow");
    return true;
});

The BugsnagEvent class

A BugsnagEvent object represents an error captured by BugSnag and is available as a parameter on an OnErrorCallback. The following properties and methods are available on a BugsnagEvent for you to query and update the captured data.

Add Feature Flag

Declare a single feature flag or experiment with variant as an optional second parameter.

event.addFeatureFlag("Checkout button color", "Blue");
event.addFeatureFlag("New checkout flow");

Add Feature Flags

Declare multiple feature flags or experiments.

event.addFeatureFlags(Arrays.asList(
    new FeatureFlag("Checkout button color", "Blue"),
    new FeatureFlag("Special offer", "Free Coffee"),
    new FeatureFlag("New checkout flow")
));

Add Metadata

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

event.addMetadata("account", "name", "Acme Co.");
event.addMetadata("account", "paying_customer", true);

If you are using the logback appender then you can add metadata to every event by adding the following in your logback.xml file:

<appender name="BUGSNAG" class="com.bugsnag.BugsnagAppender">
    ...
    <metaData>
        <tab>
            <name>system resources</name>
            <key>
                <name>memory</name>
                <value>10MB</value>
            </key>
        </tab>
    </metaData>
</appender>

It is also possible to add metadata to all events on the current thread, see Thread metadata.

API Key

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.setApiKey("your-other-api-key-here");

App

Information set by the notifier about your app can be found via the getApp() method:

property type description
App type String The application type, set via App Type
App version String The application version, set via App Version
Release stage String The release stage, defaults to production

These values can be accessed and amended if necessary:

Map<String, Object> app = event.getApp();
String appVersion = (String) app.get("version");

Clear Feature Flag

Remove a single feature flag or experiment.

event.clearFeatureFlag("Checkout button color");

Clear Feature Flags

Remove all feature flags and experiments.

event.clearFeatureFlags();

Clear Metadata

Clears a section of metadata so it will not be sent to BugSnag. Also see Add Metadata.

event.clearMetadata("system resources");

Context

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

event.setContext("User settings");

Device

Information set by the notifier about the device can be found via the getDevice() method:

property type description
Hostname String The name of the localhost
Locale String The default locale for the JVM instance
OS architecture String The value of the os.arch system property
OS name String The value of the os.name system property
OS version String The value of the os.version system property
Runtime name String The value of the java.runtime.name system property
Runtime version String The value of the java.runtime.version system property

These values can be accessed and amended if necessary:

Map<String, Object> device = event.getDevice();
String hostname = (String) device.get("hostname");

Get Exception

Returns the Throwable that triggered this error event.

Throwable throwable = event.getException();
if (throwable instanceof SpecificException) {
    // Handle specific exception type
}

Get Exception Message

Returns the message from the exception that is being reported.

String message = event.getExceptionMessage();

Get Exception Name

Returns the fully-qualified class name of the exception that is being reported.

String className = event.getExceptionName();

Grouping Hash

Sets the groupingHash used by BugSnag to manually override the default grouping technique. This is an advanced option, and should be used with care.

Any errors that are sent to BugSnag that have the same groupingHash will be grouped as one.

String groupingHash = "f8803769f3e293dfcabdb6dec5100b8c52c6ae6b";
event.setGroupingHash(groupingHash);

For more information, see our Error Grouping guide.

Set Exception Name

Sets the class name of the exception that is being reported. This allows you to customize how the error appears in the BugSnag dashboard.

event.setExceptionName("CustomErrorType");

Set Severity

Overrides the severity of the error. Valid severities are ERROR, WARNING and INFO.

event.setSeverity(Severity.WARNING);

Set User

Set information about the user the error occurred for. Details can also be set individually, see Set User ID, Set User Email and Set User Name.

event.setUser("12345", "user@example.com", "User Name");

Set User Email

Set the email address of the user the error occurred for. Also see Set User.

event.setUserEmail("user@example.com");

Set User ID

Set an identifier for the user the error occurred for. Also see Set User.

event.setUserId("12345");

Set User Name

Set the name of the user the error occurred for. Also see Set User.

event.setUserName("User Name");

User

Information about the user can be accessed via the getUser() method:

Map<String, String> user = event.getUser();
String userId = user.get("id");
String userEmail = user.get("email");
String userName = user.get("name");