• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ruby-grape / grape / 30491073836

29 Jul 2026 09:06PM UTC coverage: 96.983% (+0.007%) from 96.976%
30491073836

Pull #2840

github

ericproulx
Answer 500 when an error response cannot be rendered

Grape::Middleware::Error#call! renders the error response from inside its own
rescue clause, so that clause never covered the rendering. An error formatter
that raised on the payload it was handed took the exception straight out
through every middleware above Grape and into the application server —
`rescue_from :all` did not help, because the failure happened after the
handler had already returned.

A rescue_from handler echoing request-derived bytes was enough to hit it:

    rescue_from(Missing) { |e| error!({ detail: e.message }, 404) }

with an invalid UTF-8 byte in the path, the JSON formatter raised
JSON::GeneratorError and the request died rather than being answered.

Guard the rendering in error_response. On failure, first retry the API's own
format with the framework's InternalServerError, whose message is a static
string and so cannot be what defeated the first attempt; if that fails too — a
formatter broken outright rather than one payload it choked on — answer
without a formatter at all. Both attempts call format_message directly instead
of re-entering error_response, so the fallback cannot recurse.

The guard sits on the rendering rather than around run_rescue_handler on
purpose. Wrapping the handler call too would have swallowed things that must
keep propagating, the deprecation raised when a handler returns a Hash among
them.

Exceptions that no rescue_from matches still propagate unchanged; only
rendering failures are caught. The exception that defeated rendering is put on
env['grape.exception'], the key the existing unrecognised-error path already
uses, so upstream loggers can still observe it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Pull Request #2840: Answer 500 when an error response cannot be rendered

1196 of 1285 branches covered (93.07%)

Branch coverage included in aggregate %.

3818 of 3885 relevant lines covered (98.28%)

26730.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.37
/lib/grape/middleware/error.rb


Source Not Available

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc