ActiveSupport::ErrorReporter is a common interface for error reporting services.

To rescue and report any unhandled error, you can use the handle method:

Rails.error.handle do
  do_something!
end

If an error is raised, it will be reported and swallowed.

Alternatively if you want to report the error but not swallow it, you can use record

Rails.error.record do
  do_something!
end

Both methods can be restricted to only handle a specific exception class

maybe_tags = Rails.error.handle(Redis::BaseError) { redis.get("tags") }

You can also pass some extra context information that may be used by the error subscribers:

Rails.error.handle(context: { section: "admin" }) do
  # ...
end

Additionally a severity can be passed along to communicate how important the error report is. severity can be one of :error, :warning, or :info. Handled errors default to the :warning severity, and unhandled ones to :error.

Both handle and record pass through the return value from the block. In the case of handle rescuing an error, a fallback can be provided. The fallback must be a callable whose result will be returned when the block raises and is handled:

user = Rails.error.handle(fallback: -> { User.anonymous }) do
  User.find_by(params)
end

Methods

Constants

SEVERITIES = %i(error warning info)

Attributes

[RW] logger

Class Public methods

new(*subscribers, logger: nil)

📝 Source code
# File activesupport/lib/active_support/error_reporter.rb, line 46
    def initialize(*subscribers, logger: nil)
      @subscribers = subscribers.flatten
      @logger = logger
    end
🔎 See on GitHub

Instance Public methods

handle(error_class = StandardError, severity: :warning, context: {}, fallback: nil)

Report any unhandled exception, and swallow it.

Rails.error.handle do
  1 + '1'
end
📝 Source code
# File activesupport/lib/active_support/error_reporter.rb, line 57
    def handle(error_class = StandardError, severity: :warning, context: {}, fallback: nil)
      yield
    rescue error_class => error
      report(error, handled: true, severity: severity, context: context)
      fallback.call if fallback
    end
🔎 See on GitHub

record(error_class = StandardError, severity: :error, context: {})

📝 Source code
# File activesupport/lib/active_support/error_reporter.rb, line 64
    def record(error_class = StandardError, severity: :error, context: {})
      yield
    rescue error_class => error
      report(error, handled: false, severity: severity, context: context)
      raise
    end
🔎 See on GitHub

report(error, handled:, severity: handled ? :warning : :error, context: {})

When the block based handle and record methods are not suitable, you can directly use report

Rails.error.report(error, handled: true)
📝 Source code
# File activesupport/lib/active_support/error_reporter.rb, line 95
    def report(error, handled:, severity: handled ? :warning : :error, context: {})
      unless SEVERITIES.include?(severity)
        raise ArgumentError, "severity must be one of #{SEVERITIES.map(&:inspect).join(", ")}, got: #{severity.inspect}"
      end

      full_context = ActiveSupport::ExecutionContext.to_h.merge(context)
      @subscribers.each do |subscriber|
        subscriber.report(error, handled: handled, severity: severity, context: full_context)
      rescue => subscriber_error
        if logger
          logger.fatal(
            "Error subscriber raised an error: #{subscriber_error.message} (#{subscriber_error.class})\n" +
            subscriber_error.backtrace.join("\n")
          )
        else
          raise
        end
      end

      nil
    end
🔎 See on GitHub

set_context(...)

Update the execution context that is accessible to error subscribers

Rails.error.set_context(section: "checkout", user_id: @user.id)

See ActiveSupport::ExecutionContext.set

📝 Source code
# File activesupport/lib/active_support/error_reporter.rb, line 88
    def set_context(...)
      ActiveSupport::ExecutionContext.set(...)
    end
🔎 See on GitHub

subscribe(subscriber)

Register a new error subscriber. The subscriber must respond to

report(Exception, handled: Boolean, context: Hash)

The report method should never raise an error.

📝 Source code
# File activesupport/lib/active_support/error_reporter.rb, line 76
    def subscribe(subscriber)
      unless subscriber.respond_to?(:report)
        raise ArgumentError, "Error subscribers must respond to #report"
      end
      @subscribers << subscriber
    end
🔎 See on GitHub