FIX: Better 0 file size detection and logging (#16116)

When creating files with create-multipart, if the file
size was somehow zero we were showing a very unhelpful
error message to the user. Now we show a nicer message,
and proactively don't call the API if we know the file
size is 0 bytes in JS, along with extra console logging
to help with debugging.
This commit is contained in:
Martin Brennan 2022-03-07 12:39:33 +10:00 committed by GitHub
parent 5f5acfa064
commit 7af01d88d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 37 additions and 4 deletions

View File

@ -116,6 +116,13 @@ export function validateUploadedFile(file, opts) {
}
}
if (file.size === 0) {
/* eslint-disable no-console */
console.warn("File with a 0 byte size detected, cancelling upload.", file);
bootbox.alert(I18n.t("post.errors.file_size_zero"));
return false;
}
// everything went fine
return true;
}

View File

@ -42,6 +42,10 @@ export default class MediaOptimizationWorkerService extends Service {
this.siteSettings
.composer_media_optimization_image_bytes_optimization_threshold
) {
this.logIfDebug(
`The file ${file.name} was less than the image optimization bytes threshold (${this.siteSettings.composer_media_optimization_image_bytes_optimization_threshold} bytes), skipping.`,
file
);
return Promise.resolve();
}
await this.ensureAvailableWorker();
@ -185,10 +189,10 @@ export default class MediaOptimizationWorkerService extends Service {
this.installPromise = null;
}
logIfDebug(message) {
logIfDebug(...messages) {
if (this.siteSettings.composer_media_optimization_debug_mode) {
// eslint-disable-next-line no-console
console.log(message);
console.log(...messages);
}
}
}

View File

@ -200,6 +200,10 @@ class UploadsController < ApplicationController
end
def validate_file_size(file_name:, file_size:)
if file_size.zero?
raise ExternalUploadValidationError.new(I18n.t("upload.size_zero_failure"))
end
if file_size_too_big?(file_name, file_size)
raise ExternalUploadValidationError.new(
I18n.t(

View File

@ -3104,6 +3104,7 @@ en:
edit: "Sorry, there was an error editing your post. Please try again."
upload: "Sorry, there was an error uploading that file. Please try again."
file_too_large: "Sorry, that file is too big (maximum size is %{max_size_kb}kb). Why not upload your large file to a cloud sharing service, then paste the link?"
file_size_zero: "Sorry, it looks like something has gone wrong, the file you are trying to upload is 0 bytes. Please try again."
file_too_large_humanized: "Sorry, that file is too big (maximum size is %{max_size}). Why not upload your large file to a cloud sharing service, then paste the link?"
too_many_uploads: "Sorry, you can only upload one file at a time."
too_many_dragged_and_dropped_files:

View File

@ -4088,6 +4088,7 @@ en:
external_upload_not_found: "The upload was not found in the external store. %{additional_detail}"
checksum_mismatch_failure: "The checksum of the file you uploaded does not match. The file contents may have changed on upload. Please try again."
cannot_promote_failure: "The upload cannot be completed, it may have already completed or previously failed."
size_zero_failure: "Sorry, it looks like something has gone wrong, the file you are trying to upload is 0 bytes. Please try again."
attachments:
too_large: "Sorry, the file you are trying to upload is too big (maximum size is %{max_size_kb}KB)."
too_large_humanized: "Sorry, the file you are trying to upload is too big (maximum size is %{max_size})."

View File

@ -25,10 +25,10 @@ function resizeWithAspect(
};
}
function logIfDebug(message) {
function logIfDebug(...messages) {
if (DedicatedWorkerGlobalScope.debugMode) {
// eslint-disable-next-line no-console
console.log(message);
console.log(...messages);
}
}

View File

@ -825,6 +825,22 @@ describe UploadsController do
expect(response.body).to include(I18n.t("upload.attachments.too_large_humanized", max_size: "1 MB"))
end
it 'returns a sensible error if the file size is 0 bytes' do
SiteSetting.authorized_extensions = "*"
stub_create_multipart_request
post "/uploads/create-multipart.json", **{
params: {
file_name: "test.zip",
file_size: 0,
upload_type: "composer",
}
}
expect(response.status).to eq(422)
expect(response.body).to include(I18n.t("upload.size_zero_failure"))
end
def stub_create_multipart_request
FileStore::S3Store.any_instance.stubs(:temporary_upload_path).returns(
"uploads/default/#{test_bucket_prefix}/temp/28fccf8259bbe75b873a2bd2564b778c/test.png"