Customizing error reports

In order to quickly reproduce and fix errors, it is often helpful to send additional application-specific diagnostic data to BugSnag.

Updating events using callbacks

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

Bugsnag.configure do |config|
  config.on_error do |event|
    # Add customer information to every event
    event.add_metadata(:account, {
      name: "Bugs Nag",
      paying_customer: true
    })

    # Add user information to every event
    event.set_user("9000", "bugs.nag@bugsnag.com", "Bugs Nag")
  end
end

# Your app code here

To add an object that responds to #call, such as a Proc or Method, use add_on_error:

Bugsnag.configure do |config|
  config.add_on_error(proc do |event|
    event.add_metadata(:account, {
      name: "Bugs Nag",
      paying_customer: true
    })
  end)

  config.add_on_error(MyClass.new.method(:a_method_name))
end

# Your app code here

See the event object for methods available inside the callback.

Previously Bugsnag.before_notify_callbacks were used to customise events. These have been deprecated and replaced with ‘on error’ callbacks.

Adding and removing callbacks

We recommend adding callbacks through the on_error 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:

callback = proc { }

Bugsnag.add_on_error(callback)
# ...
Bugsnag.remove_on_error(callback)

Discarding events

If you want to prevent an event from being sent to BugSnag, you can return false within an add_on_error callback. When processing events in a queue, failures will usually be automatically retried. Reporting all the failures to BugSnag may not be desirable, since you’ll be getting duplicate reports and if a subsequent retry succeeds you may not even have a bug that needs fixing. You can avoid this by discarding the BugSnag events, using a callback, until the underlying queue event has reach a certain number of retries.

Bugsnag.configure do |config|
  config.add_on_error(proc do |event|

    next unless event.metadata.key?(:sidekiq)
    msg = event.metadata[:sidekiq][:msg]

    # always notify if this job won't be retried
    next if msg["retry"] == false

    # determine how many times Sidekiq will retry this job
    max_retries = if msg["retry"].is_a?(Integer)
      msg["retry"]
    else
      Sidekiq.options.fetch(:max_retries, Sidekiq::JobRetry::DEFAULT_MAX_RETRY_ATTEMPTS)
    end

    # discard events apart from the last failed attempt when retry limit is hit
    # note: retry_count is 0 indexed and only exists from first retry onwards.
    number_of_retry = msg.fetch("retry_count", -1) + 1
    if number_of_retry < max_retries
      false
    end
  end)
end

Custom error diagnostic data

If you are using custom error classes within your application, diagnostic data can be automatically attached to each event within the exception class itself.

This is achieved by creating a bugsnag_meta_data function on the custom error class that returns a hash with the data you wish to attach.

class MyCustomError < StandardError
  attr_reader :metadata
  def initialize(message, metadata)
    super(message)
    @metadata = metadata
  end

  def bugsnag_meta_data
     {tabname: metadata}
  end
end

Bugsnag.notify(MyCustomError.new("Error message", value1: '1', value2: {nested: 3}))

This will add a tab with the name tabname on the dashboard with the corresponding data listed in it.

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, use the add_metadata method in your configure block.

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

Bugsnag.configure do |config|
  config.add_metadata(:company, {
    name: 'Acme Co.',
    country: 'uk'
  })
end

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

Bugsnag.add_metadata(:company, {
  name: 'Acme Co.',
  country: 'uk'
})
# ...
Bugsnag.clear_metadata(:company)

The event object

add_feature_flag

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

event.add_feature_flag('Checkout button color', 'Blue')
event.add_feature_flag('New checkout flow')

For more information, see Feature flags & experiments.

add_feature_flags

Declare multiple feature flags or experiments.

event.add_feature_flags(
  [
    Bugsnag::FeatureFlag.new('Checkout button color', 'Blue')
    Bugsnag::FeatureFlag.new('New checkout flow')
  ]
)

For more information, see Feature flags & experiments.

add_metadata

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:

event.add_metadata(:company, :name, 'Acme Co.')

Alternatively a Hash can be added to a section:

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

add_tab

Call add_tab on an event object to add a tab to the event so that it would appear on your dashboard.

event.add_tab(:user_info, { name: "Bugs Nag" })

The first parameter is the tab name that will appear in the event and the second is the key, value list that will be displayed in the tab.

Deprecated: Use add_metadata instead.

api_key

Set the project API key for the event. The API key is normally set in the configuration, but it can be overridden to report to a different API key in some situations.

event.api_key = 'your-api-key-here'

Customize or filter breadcrumbs to be sent with the event. Modified breadcrumbs will not be validated again.

event.breadcrumbs.each { |breadcrumb| breadcrumb.metadata = {} } # Clear the metadata

clear_feature_flag

Remove a single feature flag or experiment.

event.clear_feature_flag('Checkout button color')

clear_feature_flags

Remove all feature flags and experiments.

event.clear_feature_flags

clear_metadata

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

# Remove a single key
event.clear_metadata(:company, :name)

# Remove an entire section
event.clear_metadata(:company)

context

Set the context of the event. This is notionally the location of the error and should be populated automatically. Context is displayed in the dashboard prominently.

event.context = 'billing'

errors

Allows you to read the class, message and stacktrace of each error in this event.

puts "#{event.errors.first.error_class}: #{event.errors.first.error_message}"
puts event.errors.first.stacktrace

exceptions

Allows you to access and modify the exceptions that will be combined into the event.

puts event.exceptions.first[:message] + ' found!'

Deprecated for reading: Use errors for reading and exceptions for modification.

grouping_hash

Sets the grouping hash of the event. All errors with the same grouping hash are grouped together. This is an advanced usage of the library and misusing it will cause your errors not to group properly in your dashboard.

event.grouping_hash = event.exceptions.first[:message] + event.exceptions.first[:errorClass]

ignore!

Calling ignore! on an event object will prevent it from being sent to BugSnag. This means that you can choose dynamically not to send an error depending on application state or the error itself.

event.ignore! if foo == 'bar'

metadata

Provides access to the metadata in the event.

event.ignore! if event.metadata[:sidekiq][:retry_count] < 2

original_error

The Exception instance used to create this event

puts event.original_error.message

remove_tab

Removes a tab completely from the event.

event.remove_tab(:user_info)

Deprecated: Use clear_metadata instead.

request

Contains data for the active HTTP request, or nil if no request data has been captured.

puts event.request[:url]

set_user

Sets the current user information.

event.set_user('1234', 'bugs.nag@bugsnag.com', 'Bugs Nag')

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

severity

Set the severity of the error. Severity can be error, warning or info.

event.severity = 'error'

summary

Creates a hashed summary of the event. Given keys are :error_class, :severity, and optionally :message.

summary = event.summary
puts "#{summary[:error_class]} occurred with message: #{summary[:message]}"

unhandled

By default this is true if the event was automatically detected by BugSnag and false if it was reported manually via Bugsnag.notify. See our product pages for more information on handled vs unhandled events.

event.unhandled = true

Changing the unhandled flag for an event will affect how it contributes to your application’s stability score.

user

Returns the current user information.

puts event.user[:id], event.user[:email], event.user[:name]

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