flow
flow copied to clipboard
Upload component doesn't fire failed events when uploading "too big files"
Description
With default settings (MultiFileReceiver), with basic spring boot project, when uploading a file larger than 1 Mb, there is an error thrown. It is also shown in the UI as red "Upload failed due to server error" message. But the error is never fired as FailedEvent. In other words this listener is never called in that kind of case:
multiFileUpload.addFailedListener(e -> {
Notification.show("Upload failed: " + e.getReason().getMessage());
});
Expected outcome
FailedEvent should be fired so that developer could handle error and give some sane message to user.
Actual outcome
Error is handled somehow, but in a bad way from UX PoV
Minimal reproducible example
Steps to reproduce
Described above.
Environment
Vaadin: 23.0.3 Flow: 23.0.3 Java: Eclipse Adoptium 17 OS: aarch64 Mac OS X 12.3.1 Browser: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Live reload: Java active (JRebel): Front end active
See also vaadin/flow-components#1087
The actual error occurs at the upload endpoint. When uploading a file that exceeds the max file size defined by the server, the upload endpoint throws an Apache TomCat FileSizeLimitExceededException exception that results in HTTP 500. Apparently, the exception is thrown before the upload request reaches StreamReceiverHandler which may explain why the Flow component doesn't get notified in this case. So, at the end of the day, this seems to be rather a Flow framework issue.
At least, I would expect the upload endpoint to return a 413 HTTP status (Payload Too Large) in order for the web component to be able to distinguish it and show a more relevant error message rather than just "An error occurred on the server".
At most, it would be nice if the Flow upload endpoint notified the Flow component about such failures with an event or something to let the developer decide how to handle it properly.
Is there any workaround for the issue until it got fixed? My current workaround when that happens is that I have to hit 'reupload' button which seems to work and successfully reuploads the file. UPD: Is there any progress and might we expect it fixed in, say, major 24 release?
To make it short, in a Spring Boot application, Vaadin uploads between 1MB and 10MB will fail. Above and below that will work. To fix or at least work around that, you need to set those two properites to appropriate values:
spring.servlet.multipart.max-file-size (default is 1MB)
spring.servlet.multipart.max-request-size (default is 10MB)
From what I can tell, the Upload component intends to handle the uploads itself. But when running in Spring Boot, its configured limits get indirectly applied when the request is parsed to access the request parameters. Those errors are swallowed, but if only max-file-size is violated the uploaded file can no longer be read afters. Seems to be an unfortunate interaction between Vaadin and Spring Boot.