From b35625dc64ced99d76cd4746670e0257c196fa4f Mon Sep 17 00:00:00 2001 From: "Kit (OpenClaw)" Date: Wed, 4 Mar 2026 19:14:14 -0500 Subject: [PATCH 1/3] WA-RAILS7-023: Add Rails.error.report hook --- core/lib/workarea/error_reporting.rb | 36 +++++++++++++ .../error-reporting.md | 53 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 core/lib/workarea/error_reporting.rb create mode 100644 docs/rails7-migration-patterns/error-reporting.md diff --git a/core/lib/workarea/error_reporting.rb b/core/lib/workarea/error_reporting.rb new file mode 100644 index 000000000..c67308938 --- /dev/null +++ b/core/lib/workarea/error_reporting.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Workarea + # Small wrapper around Rails 7.1+'s error reporting API. + # + # Rails.error.report is an additive mechanism which can be configured by host + # applications (or plugins) to forward handled exceptions to Sentry, Bugsnag, + # etc. Workarea itself intentionally does not hard-code a specific provider. + module ErrorReporting + class << self + # @param error [Exception] + # @param handled [Boolean] whether the exception was handled/swallowed + # @param severity [Symbol] :error, :warning, :info + # @param context [Hash] additional structured context + def report(error, handled: true, severity: :error, context: {}) + return unless rails_error_reporter_available? + + Rails.error.report( + error, + handled: handled, + severity: severity, + context: context + ) + rescue StandardError + # Never allow error reporting failures to impact runtime behavior. + nil + end + + private + + def rails_error_reporter_available? + defined?(Rails) && Rails.respond_to?(:error) && Rails.error.respond_to?(:report) + end + end + end +end diff --git a/docs/rails7-migration-patterns/error-reporting.md b/docs/rails7-migration-patterns/error-reporting.md new file mode 100644 index 000000000..74e6ec8eb --- /dev/null +++ b/docs/rails7-migration-patterns/error-reporting.md @@ -0,0 +1,53 @@ +# Error reporting (Rails 7.1+) + +Rails 7.1 introduced a framework-level error reporting API: + +- `Rails.error.report(exception, handled:, severity:, context:)` + +This is implemented by `ActiveSupport::ErrorReporter` and is intended to be +**configured by the host application** (or an integration gem) to forward handled +exceptions to a provider (Sentry, Bugsnag, Honeybadger, etc.). + +## Current Workarea behavior + +Workarea **does not ship with a bundled error reporting provider**. + +Instead, Workarea relies on the host application to configure an error reporting +solution at the Rack / Rails level. + +Examples: + +- Storefront error pages set `request.env['rack.exception']` in + `Workarea::Storefront::ErrorsController#internal` so Rack middleware (and error + reporters that hook into it) can see the exception. +- Workarea has optional provider integrations via separate plugins (e.g. + `workarea-sentry`). + +In core Workarea code, most exceptions are either: + +- Raised normally (and therefore captured by the host app’s exception handling), or +- Rescued and logged in a few places where Workarea intentionally swallows the + error (for example: version checks / telemetry-like pings). + +## Decision + +**Adopt Rails 7.1’s error reporting API as an additive, opt-in hook.** + +This means: + +- Workarea will call `Rails.error.report` **only when available**. +- Workarea will not require any provider. +- Existing error handling continues to work unchanged. + +This is useful primarily for *handled/swallowed* exceptions where otherwise the +host app may never learn about the error. + +## Implementation notes + +- Add `Workarea::ErrorReporting.report` as a small wrapper around + `Rails.error.report`. +- Use it in places where Workarea rescues and continues (handled errors), with + `severity: :warning` and some lightweight context. + +Host applications can configure Rails’ error reporter via `config.error_reporter` +(or via a provider gem that integrates with `ActiveSupport::ErrorReporter`). From af6ffe263632613cb58943fe6de9662e880e2be7 Mon Sep 17 00:00:00 2001 From: "Kit (OpenClaw)" Date: Wed, 4 Mar 2026 19:14:46 -0500 Subject: [PATCH 2/3] Report handled errors via Workarea::ErrorReporting --- core/app/models/workarea/checkout/fraud/analyzer.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/app/models/workarea/checkout/fraud/analyzer.rb b/core/app/models/workarea/checkout/fraud/analyzer.rb index 39aed1da4..60d2a94f6 100644 --- a/core/app/models/workarea/checkout/fraud/analyzer.rb +++ b/core/app/models/workarea/checkout/fraud/analyzer.rb @@ -18,6 +18,17 @@ def decide! begin decision = make_decision.tap { |r| r.analyzer = self.class.name } rescue => e + Workarea::ErrorReporting.report( + e, + handled: true, + severity: :warning, + context: { + analyzer: self.class.name, + order_id: order&.id, + checkout_class: checkout.class.name + } + ) + decision = error_decision(e.message) ensure order.set_fraud_decision!(decision) From 07b09ea2b4efce3e7d945f09f81ff7cd5e9e74ab Mon Sep 17 00:00:00 2001 From: "Kit (OpenClaw)" Date: Wed, 4 Mar 2026 19:15:42 -0500 Subject: [PATCH 3/3] Report swallowed network errors via Rails.error.report --- core/lib/workarea/latest_version.rb | 7 +++++++ core/lib/workarea/ping_home_base.rb | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/core/lib/workarea/latest_version.rb b/core/lib/workarea/latest_version.rb index 6f02d9eaf..2554aef8c 100644 --- a/core/lib/workarea/latest_version.rb +++ b/core/lib/workarea/latest_version.rb @@ -14,6 +14,13 @@ def self.get JSON.parse(response.body)['version'] end rescue Exception => e + Workarea::ErrorReporting.report( + e, + handled: true, + severity: :warning, + context: { service: 'rubygems.org', url: 'https://rubygems.org/api/v1/gems/workarea.json' } + ) + Rails.logger.error '-------------------------------------' Rails.logger.error "There was an error contacting rubygems.org!" Rails.logger.error e.class diff --git a/core/lib/workarea/ping_home_base.rb b/core/lib/workarea/ping_home_base.rb index e2ab0064e..87f51f5aa 100644 --- a/core/lib/workarea/ping_home_base.rb +++ b/core/lib/workarea/ping_home_base.rb @@ -19,6 +19,13 @@ def ping http.start { |h| h.request(request) } rescue Exception => e + Workarea::ErrorReporting.report( + e, + handled: true, + severity: :warning, + context: { service: 'homebase.weblinc.com', url: URL } + ) + Rails.logger.error '-------------------------------------' Rails.logger.error "There was an error contacting #{URL}!" Rails.logger.error e.class