Skip to content

[Errors] Centralized error reporting interface #232

@rsamoilov

Description

@rsamoilov

Description

Rage has multiple independent components that catch and log exceptions internally — controllers, background tasks, Cable connections, Cable channels, event subscribers, and SSE streams. Currently, there is no way to tell the framework where to forward these exceptions beyond the built-in logger.

In practice, most applications use an external error tracking service (e.g. Sentry, Bugsnag, Rollbar). Today, the only way to get Rage-caught exceptions into these services is to manually rescue errors in each component and forward them yourself. This is repetitive and easy to miss.

The goal of Rage::Errors is to provide a centralized hook that lets users tell Rage: "when you catch an exception, also report it here". This is not a general-purpose error reporting abstraction or a replacement for the error tracking service's SDK — it's a way for the framework to forward exceptions it already catches.

Proposed interface

Register one or more reporters — any object that responds to call:

# config/application.rb
Rage.configure do
  config.errors << SentryReporter.new
  config.errors << InternalMetricsReporter.new
end

Where a reporter looks like:

class SentryReporter
  def call(exception, context: {})
    Sentry.capture_exception(exception, extra: context)
  end
end

Users should also be able to report errors manually using the Rage::Errors interface:

Rage::Errors.report(exception)

Design considerations

These are open questions that should be addressed in the design proposal:

  • Logging behavior when a reporter is set. The framework currently logs all caught exceptions. Should it continue to do so when a reporter is configured?
  • Multiple reporters. The interface above supports multiple reporters. The implementation should iterate over all subscribers and call call on each. Consider what happens if one reporter raises an exception.
  • Duplicate errors. Should the framework attempt to deduplicate errors before reporting?
  • Reporting unraised exceptions. Rage::Errors.report(SomeError.new("...")) should work for manually created exceptions.
  • Reporting interface Consider whether call should accept an optional severity/source argument.
  • Integration points. Identify all the places in the codebase where Rage rescues exceptions (controllers, deferred tasks, Cable connections/channels, event subscribers, SSE streams) and ensure each one calls the reporting hook.

Before You Start

This issue requires a design proposal before implementation. Please open a discussion or comment on this issue with a high-level plan that outlines:

  1. The public API (confirming or adjusting the interface above).
  2. How reporters will be registered and invoked.
  3. The list of integration points in the codebase where reporting will be added.
  4. How the edge cases above will be handled.

PRs without prior design discussion are unlikely to be accepted.

Tips

  • Search the codebase for rescue and Rage.logger.error to find all the places where Rage catches and logs exceptions — these are the integration points.
  • Check the architecture doc that shows how Rage's core components interact with each other and outlines the design principles.
  • For reference, see Rails' Rails.error API. Note that Rage::Errors has a different goal — it's not about reducing boilerplate or providing a standard reporting interface, it's about letting the framework forward exceptions it already catches.
  • Feel free to ask any questions or request help in the comments below!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions