Skip to content

Commit 097d0b3

Browse files
authored
Merge pull request rails#46131 from Shopify/avoid-double-error-report
`Rails.error.report` now marks errors as reported to avoid reporting them twice
2 parents b7eaebe + a6dbfcd commit 097d0b3

File tree

4 files changed

+34
-0
lines changed

4 files changed

+34
-0
lines changed

activesupport/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
* `Rails.error.report` now marks errors as reported to avoid reporting them twice.
2+
3+
In some cases, users might want to report errors explicitly with some extra context
4+
before letting it bubble up.
5+
6+
This also allows to safely catch and report errors outside of the execution context.
7+
8+
*Jean Boussier*
9+
110
* Add `Rails.application.message_verifiers` as a central point to configure
211
and create message verifiers for an application.
312

activesupport/lib/active_support/error_reporter.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ def set_context(...)
166166
# Rails.error.report(error)
167167
#
168168
def report(error, handled: true, severity: handled ? :warning : :error, context: {}, source: DEFAULT_SOURCE)
169+
return if error.instance_variable_get(:@__rails_error_reported)
170+
169171
unless SEVERITIES.include?(severity)
170172
raise ArgumentError, "severity must be one of #{SEVERITIES.map(&:inspect).join(", ")}, got: #{severity.inspect}"
171173
end
@@ -187,6 +189,10 @@ def report(error, handled: true, severity: handled ? :warning : :error, context:
187189
end
188190
end
189191

192+
unless error.frozen?
193+
error.instance_variable_set(:@__rails_error_reported, true)
194+
end
195+
190196
nil
191197
end
192198
end

activesupport/test/error_reporter_test.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,24 @@ class ErrorReporterTest < ActiveSupport::TestCase
178178
assert_equal :error, @subscriber.events.dig(0, 2)
179179
end
180180

181+
test "report errors only once" do
182+
assert_difference -> { @subscriber.events.size }, +1 do
183+
@reporter.report(@error, handled: false)
184+
end
185+
186+
assert_no_difference -> { @subscriber.events.size } do
187+
3.times do
188+
@reporter.report(@error, handled: false)
189+
end
190+
end
191+
end
192+
193+
test "can report frozen exceptions" do
194+
assert_difference -> { @subscriber.events.size }, +1 do
195+
@reporter.report(@error.freeze, handled: false)
196+
end
197+
end
198+
181199
class FailingErrorSubscriber
182200
Error = Class.new(StandardError)
183201

activesupport/test/executor_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def test_wrap_report_errors
2929
end
3030
assert_equal [error, false, :error, "application.active_support", {}], subscriber.events.last
3131

32+
error = DummyError.new("Oops")
3233
assert_raises DummyError do
3334
executor.wrap(source: "custom") do
3435
raise error

0 commit comments

Comments
 (0)