intridea/grape — pull request #544 by xevix (2013-12-30 19:18:45+00:00)
Title: Rescue Child Errors In Error Middleware

# Summary #

This enables the behavior desired in #542

Assuming this exception hierarchy:

```ruby
module APIErrors
class ParentError < StandardError; end
class Child < ParentError; end
end
```

And the following rescue_from calls:

```ruby
rescue_from Grape::Exceptions::ValidationErrors do |e|
Rack::Response.new(
status: e.status,
message: e.message,
errors: e.errors
}.to_json, e.status)
end
rescue_from APIErrors::ParentError, rescue_children: true do |e|
Rack::Response.new({
error: "#{e.class} error",
message: e.message
}.to_json, e.status)
end
```

Then the following will be handled by the first handler above.

```ruby
raise Grape::Exceptions::ValidationErrors, "bad data"
```

And the following will all be handled by the second handler.

```ruby
raise APIErrors::ParentError, "I'm going to be rescued!"
raise APIErrors::Child, "I'm going to be rescued too!"
```

# Notes #
* Existing behavior of only handling parent errors is maintained as the default code path, so performance differences should be negligible (but please confirm)
* List of handled errors was removed, since it's redundant (an error is handled if rescue_all is set or if it has a handler)
* Two sets of handlers, the existing __rescue_handlers__ and a new __rescue_children_handlers__ were used, as a tradeoff for complexity of embedding one in the other
* The imbue() function does not recursively parse hashes/arrays to merge/concat, so options get overridden on multiple calls
* Marking every single handler with a children? bool is a waste of time/memory