file icon indicating copy to clipboard operation
file copied to clipboard

File.toString causes a runtime exception

Open jgrenat opened this issue 4 years ago • 1 comments

Hello!

We're using elm/file in our project to upload files from the user's computer. In some cases, we've had a runtime error:

Runtime error stacktrace

It's hard to explain how to reproduce the case, because for us it concerns files synchronized with One Drive. When the One Drive application is not launched, we can't open some files (for example with the Excel desktop app).

SSCCE

https://ellie-app.com/8Nkyf2KYWPSa1 (but I don't know how to reproduce the proper "state" for the file to upload)

Cause

The problem is in this file:

function _File_toString(blob)
{
	return __Scheduler_binding(function(callback)
	{
		var reader = new FileReader();
		reader.addEventListener('loadend', function() {
			callback(__Scheduler_succeed(reader.result));
		});
		reader.readAsText(blob);
		return function() { reader.abort(); };
	});
}

We're assuming that the loadend event means that everything was successful, but the documentation says that it is also called if the read operation fails. So we need to check before wrapping it in a succeed (here, the reader.result value is null) or maybe listen to load instead.

The problem should be the same with File.toUrl and File.toBytes.

jgrenat avatar May 07 '20 13:05 jgrenat

Hi :wave:

I'm experiencing a similar issue with File.toBytes.

The scenario where the error occurs is the following: There is a file loading button. The type of the message processing the loaded is SomeMsg File.File, or when the user can upload multiple files, SomeMsg File.File (List File.File). When the user clicks the button and enters the file upload dialog of their operating system, they can indeed only select one or multiple files, pretty nice. But, when using drag and drop, they can also drag and drop and thus load a folder. The folder is then loaded into the File.File, which works at first, but causes a runtime error when calling File.toBytes on it.

I'm working around this by checking the the file extension of the loaded file/folder with File.mime. In my case, I want to process a ZIP file, so I only call File.toBytes when the file extension is "application/zip". But it seems that the file extension depends on the file name, so when the user loads a folder with a name ending in .zip, it will still cause the runtime error. This is very unlikely to happen in practice, so I can live with that. Perhaps there are other use cases where the loaded file should not be of any specific type, and then this workaround would not be applicable.

For reproduction, I have made an Ellie where I have extended this drag and drop file loading example by also calling File.toBytes on the loaded file. When you drag and drop a folder into the upload field, you will see the runtime error. (Or at least I do, using Ubuntu and Firefox, and dragging a folder from the Ubuntu File app.)

davidpomerenke avatar Jul 12 '21 14:07 davidpomerenke