Skip to content

feat: handle exceptions gracefully#98

Open
andheiberg wants to merge 3 commits intomainfrom
rescue-aggresively
Open

feat: handle exceptions gracefully#98
andheiberg wants to merge 3 commits intomainfrom
rescue-aggresively

Conversation

@andheiberg
Copy link

Should an exception be raised while serisalising, compressing, writing to cache, fetching from cache, decompressing or deserialising we would previously raise that exception and return an error.

With this PR the exception will be caught and the app run as if the response_cache gem was disabled.

@andheiberg andheiberg self-assigned this Feb 6, 2026
@andheiberg andheiberg requested a review from a team as a code owner February 6, 2026 16:34
content_encoding,
compression_level: env["cacheable.compression_level"],
)
begin
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this could go in a helper method now?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying it out I would say it makes the code worse.

The begin/rescue in call was already clear. Now you have a compress_and_cache_response method that shadows ResponseBank.write_to_cache, takes 5 positional arguments, and mutates headers and env as side effects. It hasn't really reduced complexity — it's just moved code around.

def compress_and_cache_response(body_string, status, headers, content_encoding, env)

Extract read_from_cache from try_to_serve_from_cache and wrap it in a
rescue block so that exceptions during cache reads, deserialization, or
decompression fall back to a normal cache miss instead of raising a 500.

Add handle_cache_exception helper with support for a custom
response_bank.on_exception callback (e.g. for error reporting to
Bugsnag/Sentry).
Wrap the compression, serialization, and cache write path in the
middleware with a begin/rescue so that failures don't cause 500 errors.
On exception the Content-Encoding header is stripped and the original
uncompressed response is served. The response_bank.on_exception callback
is invoked if set.
@andheiberg andheiberg force-pushed the rescue-aggresively branch 2 times, most recently from bdebbb3 to 8ec2378 Compare February 9, 2026 09:52
headers.delete('Content-Encoding')
end
end
rescue => exception
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some exceptions (those not inheriting from StandardError) might still slip through, but I think it's OK because these exceptions should only be used when it's not recoverable (e.g. SyntaxError, NoMemoryError).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments