mirror of https://github.com/rails/rails
Allow ErrorReporter to handle several error classes
`Rails.error.handle` and `Rails.error.record` are able to filter by list of serveral error classes now, for example like this: ```ruby Rails.error.handle(ArgumentError, TypeError) do [1, 2, 3].first(x) # where `x` might be `-4` or `'4'` end ```
This commit is contained in:
parent
b96ddea5f0
commit
1a9b887c0c
|
@ -1,3 +1,14 @@
|
|||
* `Rails.error.handle` and `Rails.error.record` filter now by multiple error classes.
|
||||
|
||||
```ruby
|
||||
Rails.error.handle(IOError, ArgumentError) do
|
||||
1 + '1' # raises TypeError
|
||||
end
|
||||
1 + 1 # TypeErrors are not IOErrors or ArgumentError, so this will *not* be handled
|
||||
```
|
||||
|
||||
*Martin Spickermann*
|
||||
|
||||
* `Class#subclasses` and `Class#descendants` now automatically filter reloaded classes.
|
||||
|
||||
Previously they could return old implementations of reloadable classes that have been
|
||||
|
|
|
@ -42,7 +42,7 @@ module ActiveSupport
|
|||
# 1 + '1'
|
||||
# end
|
||||
#
|
||||
# Can be restricted to handle only a specific error class:
|
||||
# Can be restricted to handle only specific error classes:
|
||||
#
|
||||
# maybe_tags = Rails.error.handle(Redis::BaseError) { redis.get("tags") }
|
||||
#
|
||||
|
@ -69,9 +69,10 @@ module ActiveSupport
|
|||
# * +:source+ - This value is passed along to subscribers to indicate the
|
||||
# source of the error. Subscribers can use this value to ignore certain
|
||||
# errors. Defaults to <tt>"application"</tt>.
|
||||
def handle(error_class = StandardError, severity: :warning, context: {}, fallback: nil, source: DEFAULT_SOURCE)
|
||||
def handle(*error_classes, severity: :warning, context: {}, fallback: nil, source: DEFAULT_SOURCE)
|
||||
error_classes = [StandardError] if error_classes.blank?
|
||||
yield
|
||||
rescue error_class => error
|
||||
rescue *error_classes => error
|
||||
report(error, handled: true, severity: severity, context: context, source: source)
|
||||
fallback.call if fallback
|
||||
end
|
||||
|
@ -84,7 +85,7 @@ module ActiveSupport
|
|||
# 1 + '1'
|
||||
# end
|
||||
#
|
||||
# Can be restricted to handle only a specific error class:
|
||||
# Can be restricted to handle only specific error classes:
|
||||
#
|
||||
# tags = Rails.error.record(Redis::BaseError) { redis.get("tags") }
|
||||
#
|
||||
|
@ -104,9 +105,10 @@ module ActiveSupport
|
|||
# * +:source+ - This value is passed along to subscribers to indicate the
|
||||
# source of the error. Subscribers can use this value to ignore certain
|
||||
# errors. Defaults to <tt>"application"</tt>.
|
||||
def record(error_class = StandardError, severity: :error, context: {}, source: DEFAULT_SOURCE)
|
||||
def record(*error_classes, severity: :error, context: {}, source: DEFAULT_SOURCE)
|
||||
error_classes = [StandardError] if error_classes.blank?
|
||||
yield
|
||||
rescue error_class => error
|
||||
rescue *error_classes => error
|
||||
report(error, handled: false, severity: severity, context: context, source: source)
|
||||
raise
|
||||
end
|
||||
|
|
|
@ -68,6 +68,23 @@ class ErrorReporterTest < ActiveSupport::TestCase
|
|||
assert_equal [], @subscriber.events
|
||||
end
|
||||
|
||||
test "#handle can be scoped to several exception classes" do
|
||||
assert_raises ArgumentError do
|
||||
@reporter.handle(NameError, NoMethodError) do
|
||||
raise ArgumentError
|
||||
end
|
||||
end
|
||||
assert_equal [], @subscriber.events
|
||||
end
|
||||
|
||||
test "#handle swallows and reports matching errors" do
|
||||
error = ArgumentError.new("Oops")
|
||||
@reporter.handle(NameError, ArgumentError) do
|
||||
raise error
|
||||
end
|
||||
assert_equal [[error, true, :warning, "application", {}]], @subscriber.events
|
||||
end
|
||||
|
||||
test "#handle passes through the return value" do
|
||||
result = @reporter.handle do
|
||||
2 + 2
|
||||
|
@ -125,6 +142,25 @@ class ErrorReporterTest < ActiveSupport::TestCase
|
|||
assert_equal [], @subscriber.events
|
||||
end
|
||||
|
||||
test "#record can be scoped to several exception classes" do
|
||||
assert_raises ArgumentError do
|
||||
@reporter.record(NameError, NoMethodError) do
|
||||
raise ArgumentError
|
||||
end
|
||||
end
|
||||
assert_equal [], @subscriber.events
|
||||
end
|
||||
|
||||
test "#record report any matching, unhandled error and re-raise them" do
|
||||
error = ArgumentError.new("Oops")
|
||||
assert_raises ArgumentError do
|
||||
@reporter.record(NameError, ArgumentError) do
|
||||
raise error
|
||||
end
|
||||
end
|
||||
assert_equal [[error, false, :error, "application", {}]], @subscriber.events
|
||||
end
|
||||
|
||||
test "#record passes through the return value" do
|
||||
result = @reporter.record do
|
||||
2 + 2
|
||||
|
|
|
@ -131,9 +131,9 @@ Rails.error.handle(context: {user_id: user.id}, severity: :info) do
|
|||
end
|
||||
```
|
||||
|
||||
### Filtering by Error Class
|
||||
### Filtering by Error Classes
|
||||
|
||||
With `Rails.error.handle` and `Rails.error.record`, you can also choose to only report errors of a certain class. For example:
|
||||
With `Rails.error.handle` and `Rails.error.record`, you can also choose to only report errors of certain classes. For example:
|
||||
|
||||
```ruby
|
||||
Rails.error.handle(IOError) do
|
||||
|
|
Loading…
Reference in New Issue