Repository navigation
Fail more gracefully from ActiveStorage missing file exceptions - #33666
georgeclaghorn merged 2 commits into
Conversation
There was a problem hiding this comment.
Let’s use bare raise instead of raise e to avoid munging the backtrace:
if e.type == "BlobNotFound"
raise ActiveStorage::FileNotFoundError
else
raise
endThere was a problem hiding this comment.
Can we extract a private handle_errors method to avoid duplicating the error handling logic in download and download_chunk?
def download_chunk(key, range)
instrument :download_chunk, key: key, range: range do
handle_errors do
_, io = blobs.get_blob(container, key, start_range: range.begin, end_range: range.exclude_end? ? range.end - 1 : range.end)
io.force_encoding(Encoding::BINARY)
end
end
endThere was a problem hiding this comment.
I was half tempted to put such a private method on the parent class (taking a service specific exception as an argument) but worried it was gonna be too much magic. Is this just needed because of the extra type checking needed for Azure errors? (Related bug fix PR #33667 that should probably do it the same way…)
There was a problem hiding this comment.
I wouldn’t put it on the parent class. It’s a service-specific method.
There was a problem hiding this comment.
You don’t need the begin/end block here:
def handle_errors
yield
rescue Azure::Core::Http::HTTPError => e
# ...
endThere was a problem hiding this comment.
Ditto: you don’t need the begin/end block here.
|
Last thing: can you please squash your commits? I think two are appropriate: one for rescuing I also think these changes merit separate changelog entries, since they're independent:
|
`ActiveStorage::Blob#download` and `ActiveStorage::Blob#open` raise `ActiveStorage::FileNotFoundError` when the corresponding file is missing from the storage service. Services translate service-specific missing object exceptions (e.g. `Google::Cloud::NotFoundError` for the GCS service and `Errno::ENOENT` for the disk service) into `ActiveStorage::FileNotFoundError`.
`ActiveStorage::DiskController#show` generates a 404 Not Found response when the requested file is missing from the disk service. It previously raised `Errno::ENOENT`.
6286b76 to
22efb2e
Compare
|
Done 👍 Is there anything to do about the errors raised in |
|
The rails/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb Lines 179 to 188 in cdee520 I’m not immediately sure what we can do about that. I’m going to think about it and merge this in the meantime. |
Fail more gracefully from ActiveStorage missing file exceptions rails/rails#33666
This PR translates service-specific missing object exceptions into one generic
ActiveStorage::FileNotFoundErrorso that the application can fail more gracefully when a missing file is accessed. Specifically, this PR letsDiskControllerrescue this error and respond with 404 instead of 500. This improves the development experience especially when working, indevelopment, with a database of Blob records that point to files in theproductionservice.Outstanding question
RepresentationsControllerdoes not presently handleActiveStorage::FileNotFoundError, since @georgeclaghorn argued it truly is exceptional for the service not to have a file that corresponds to a specific blob in the database. I don’t disagree with this, but hope we can nevertheless find a way to reduce the flood of stack traces that fill ourdevelopmentlogs when loading an index view that tries to display many thumbnails of images stored in ourproductionservice.Related issue
Resolves #33647