Skip to content

Commit df35d93

Browse files
authored
Merge pull request rails#43719 from kmcphillips/error-reporter-fallback-callable
Require the ErrorReporter#handle fallback to be a callable
2 parents 481343e + d0eeee0 commit df35d93

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

activesupport/lib/active_support/error_reporter.rb

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module ActiveSupport
1111
#
1212
# If an error is raised, it will be reported and swallowed.
1313
#
14-
# Alternatively if you want to report the error but not swallow it, you can use `record`
14+
# Alternatively if you want to report the error but not swallow it, you can use +record+
1515
#
1616
# Rails.error.record do
1717
# do_something!
@@ -31,10 +31,11 @@ module ActiveSupport
3131
# +severity+ can be one of +:error+, +:warning+ or +:info+. Handled errors default to the +:warning+
3232
# severity, and unhandled ones to +error+.
3333
#
34-
# Both `handle` and `record` pass through the return value from the block. In the special case of `handle` handling an
35-
# error, a fallback value can be provided that will be returned:
34+
# Both +handle+ and +record+ pass through the return value from the block. In the case of +handle+
35+
# rescuing an error, a fallback can be provided. The fallback must be a callable whose result will
36+
# be returned when the block raises and is handled:
3637
#
37-
# user = Rails.error.handle(fallback: User.anonymous) do
38+
# user = Rails.error.handle(fallback: -> { User.anonymous }) do
3839
# User.find_by(params)
3940
# end
4041
class ErrorReporter
@@ -57,7 +58,7 @@ def handle(error_class = StandardError, severity: :warning, context: {}, fallbac
5758
yield
5859
rescue error_class => error
5960
report(error, handled: true, severity: severity, context: context)
60-
fallback
61+
fallback.call if fallback
6162
end
6263

6364
def record(error_class = StandardError, severity: :error, context: {})
@@ -90,7 +91,7 @@ def set_context(...)
9091

9192
# When the block based +handle+ and +record+ methods are not suitable, you can directly use +report+
9293
#
93-
# Rails.error.report(error, handled: true)
94+
# Rails.error.report(error, handled: true)
9495
def report(error, handled:, severity: handled ? :warning : :error, context: {})
9596
unless SEVERITIES.include?(severity)
9697
raise ArgumentError, "severity must be one of #{SEVERITIES.map(&:inspect).join(", ")}, got: #{severity.inspect}"

activesupport/test/error_reporter_test.rb

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,27 @@ def report(error, handled:, severity:, context:)
7373
assert_nil result
7474
end
7575

76-
test "#handle returns a fallback value on handled raise" do
77-
expected = "four"
78-
result = @reporter.handle(fallback: expected) do
76+
test "#handle returns the value of the fallback as a proc on handled raise" do
77+
result = @reporter.handle(fallback: -> { 2 + 2 }) do
7978
raise StandardError
80-
2 + 2
8179
end
82-
assert_equal expected, result
80+
assert_equal 4, result
81+
end
82+
83+
test "#handle raises if the fallback is not a callable" do
84+
assert_raises NoMethodError do
85+
@reporter.handle(fallback: "four") do
86+
raise StandardError
87+
end
88+
end
89+
end
90+
91+
test "#handle raises the error up if fallback is a proc that then also raises" do
92+
assert_raises ArgumentError do
93+
@reporter.handle(fallback: -> { raise ArgumentError }) do
94+
raise StandardError
95+
end
96+
end
8397
end
8498

8599
test "#record report any unhandled error and re-raise them" do

0 commit comments

Comments
 (0)