Skip to content

Commit ac751ed

Browse files
committed
Allow a fallback value to be returned from Rails.error.handle
1 parent 89b1cc4 commit ac751ed

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed

activesupport/lib/active_support/error_reporter.rb

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,24 @@ module ActiveSupport
1919
#
2020
# Both methods can be restricted to only handle a specific exception class
2121
#
22-
# maybe_tags = Rails.error.handle(Redis::BaseError) { redis.get("tags") }
22+
# maybe_tags = Rails.error.handle(Redis::BaseError) { redis.get("tags") }
2323
#
2424
# You can also pass some extra context information that may be used by the error subscribers:
2525
#
26-
# Rails.error.handle(context: { section: "admin" }) do
27-
# # ...
28-
# end
26+
# Rails.error.handle(context: { section: "admin" }) do
27+
# # ...
28+
# end
2929
#
3030
# Additionally a +severity+ can be passed along to communicate how important the error report is.
3131
# +severity+ can be one of +:error+, +:warning+ or +:info+. Handled errors default to the +:warning+
3232
# severity, and unhandled ones to +error+.
33+
#
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:
36+
#
37+
# user = Rails.error.handle(fallback: User.anonymous) do
38+
# User.find_by(params)
39+
# end
3340
class ErrorReporter
3441
SEVERITIES = %i(error warning info)
3542

@@ -42,15 +49,15 @@ def initialize(*subscribers, logger: nil)
4249

4350
# Report any unhandled exception, and swallow it.
4451
#
45-
# Rails.error.handle do
46-
# 1 + '1'
47-
# end
52+
# Rails.error.handle do
53+
# 1 + '1'
54+
# end
4855
#
49-
def handle(error_class = StandardError, severity: :warning, context: {})
56+
def handle(error_class = StandardError, severity: :warning, context: {}, fallback: nil)
5057
yield
5158
rescue error_class => error
5259
report(error, handled: true, severity: severity, context: context)
53-
nil
60+
fallback
5461
end
5562

5663
def record(error_class = StandardError, severity: :error, context: {})

activesupport/test/error_reporter_test.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,30 @@ def report(error, handled:, severity:, context:)
5858
assert_equal [], @subscriber.events
5959
end
6060

61+
test "#handle passes through the return value" do
62+
result = @reporter.handle do
63+
2 + 2
64+
end
65+
assert_equal 4, result
66+
end
67+
68+
test "#handle returns nil on handled raise" do
69+
result = @reporter.handle do
70+
raise StandardError
71+
2 + 2
72+
end
73+
assert_nil result
74+
end
75+
76+
test "#handle returns a fallback value on handled raise" do
77+
expected = "four"
78+
result = @reporter.handle(fallback: expected) do
79+
raise StandardError
80+
2 + 2
81+
end
82+
assert_equal expected, result
83+
end
84+
6185
test "#record report any unhandled error and re-raise them" do
6286
error = ArgumentError.new("Oops")
6387
assert_raises ArgumentError do
@@ -77,6 +101,13 @@ def report(error, handled:, severity:, context:)
77101
assert_equal [], @subscriber.events
78102
end
79103

104+
test "#record passes through the return value" do
105+
result = @reporter.record do
106+
2 + 2
107+
end
108+
assert_equal 4, result
109+
end
110+
80111
test "can have multiple subscribers" do
81112
second_subscriber = ErrorSubscriber.new
82113
@reporter.subscribe(second_subscriber)

0 commit comments

Comments
 (0)