Merge pull request #2474 from basecamp/fix-crash-during-export

Fix crash due to missing ActiveStorage URL options
This commit is contained in:
Stanko Krtalić
2026-02-02 21:51:49 +01:00
committed by GitHub
2 changed files with 20 additions and 34 deletions
+7 -2
View File
@@ -20,7 +20,7 @@ class Export < ApplicationRecord
def build
processing!
with_account_context do
with_context do
ZipFile.create_for(file, filename: filename) do |zip|
populate_zip(zip)
end
@@ -45,9 +45,14 @@ class Export < ApplicationRecord
"fizzy-export-#{id}.zip"
end
def with_account_context
def with_context
Current.set(account: account) do
old_url_options = ActiveStorage::Current.url_options
ActiveStorage::Current.url_options = Rails.application.routes.default_url_options
yield
ensure
ActiveStorage::Current.url_options = old_url_options
end
end
+13 -32
View File
@@ -40,38 +40,19 @@ class ZipFile
writer = Writer.new
begin
# Use S3's upload_stream directly for write-based streaming.
# ActiveStorage's upload method expects a read-based IO, but ZipKit
# needs a write-based stream. The TransferManager's upload_stream
# yields a writable IO that we can stream directly to.
service.send(:upload_stream,
key: blob.key,
content_type: "application/zip",
part_size: 100.megabytes
) do |write_stream|
write_stream.binmode
writer.stream_to(write_stream)
yield writer
writer.close
end
rescue Aws::S3::MultipartUploadError => e
if defined?(Sentry)
Sentry.set_context("zip_file_upload", {
blob_key: blob.key,
writer_byte_size: writer.byte_size,
error_class: e.class.name,
error_message: e.message,
nested_errors: e.errors.map do |err|
{
class: err.class.name,
message: err.message,
backtrace: err.backtrace&.first(20)
}
end
})
end
raise
# Use S3's upload_stream directly for write-based streaming.
# ActiveStorage's upload method expects a read-based IO, but ZipKit
# needs a write-based stream. The TransferManager's upload_stream
# yields a writable IO that we can stream directly to.
service.send(:upload_stream,
key: blob.key,
content_type: "application/zip",
part_size: 100.megabytes
) do |write_stream|
write_stream.binmode
writer.stream_to(write_stream)
yield writer
writer.close
end
blob.update!(byte_size: writer.byte_size, checksum: writer.checksum)