Skip to content

Commit b779a01

Browse files
authored
Merge pull request rails#55003 from Shopify/amomchilov/report-sets-cause
`ActiveSupport::ErrorReporter#report` assigns a cause to unraised exceptions
2 parents 76e41b5 + f9a7ef8 commit b779a01

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

activesupport/lib/active_support/error_reporter.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -276,14 +276,12 @@ def report(error, handled: true, severity: handled ? :warning : :error, context:
276276

277277
private
278278
def ensure_backtrace(error)
279-
return if error.frozen? # re-raising won't add a backtrace
279+
return if error.frozen? # re-raising won't add a backtrace or set the cause
280280
return unless error.backtrace.nil?
281281

282282
begin
283-
# We could use Exception#set_backtrace, but until Ruby 3.4
284-
# it only support setting `Exception#backtrace` and not
285-
# `Exception#backtrace_locations`. So raising the exception
286-
# is a good way to build a real backtrace.
283+
# As of Ruby 3.4, we could use Exception#set_backtrace to set the backtrace,
284+
# but there's nothing like Exception#set_cause. Raising+rescuing is the only way to set the cause.
287285
raise error
288286
rescue error.class => error
289287
end

activesupport/test/error_reporter_test.rb

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,21 @@ class ErrorReporterTest < ActiveSupport::TestCase
166166
assert_nil error.backtrace
167167
assert_nil error.backtrace_locations
168168

169-
assert_nil @reporter.report(error)
170-
assert_not_predicate error.backtrace, :empty?
171-
assert_not_predicate error.backtrace_locations, :empty?
169+
@reporter.report(error)
170+
171+
assert error.backtrace.first.start_with?(__FILE__)
172+
assert_equal __FILE__, error.backtrace_locations.first.path
173+
end
174+
175+
test "#report assigns a cause if it's missing" do
176+
raise "the original cause"
177+
rescue => cause
178+
new_error = StandardError.new("A new error that should wrap the StandardError")
179+
assert_nil new_error.cause
180+
181+
@reporter.report(new_error)
182+
183+
assert_same cause, new_error.cause
172184
end
173185

174186
test "#record passes through the return value" do

0 commit comments

Comments
 (0)