Search code examples
node.jselectronfsenoent

Electron app createWriteStream throwing ENOENT error


I'm trying to download files to the filesystem in an electron app. My code, in the main thread, looks like this:

const dir = `${__dirname}/media`;
if (!fs.existsSync(dir)){
    fs.mkdirSync(dir);
}

const file = fs.createWriteStream(`${dir}/${name}`);
file.on("open", function() {
    const request = http.get(url, function(response) {
        response.pipe(file);

        response.on('end', function() {
            file.close();
            ...
        });
    });

    request.on('error', function(err) {
        ...
    });
});

This works when running in development using electron . But after I build it with electron-builder, I get the error in an alert:

Uncaught Exception: Error: ENOENT, media/uploads_2016_02_BASF_Holistic_Program.jpg not found in /Users/nicholasstephan/Desktop/XXXXXXX/dist/Mac/XXXXXX.app/Contents/Resources/app.asar at notFoundError (ELECTRON_ASAR.js:109:19) at Object.module.(anonymous function) [as open] (ELECTRON_ASAR.js:209:16) at WriteStream.open (fs.js:1890:6) at new WriteStream (fs.js:1876:10) at Object.fs.createWriteStream (fs.js:1831:10) at next (/Users/nicholasstephan/Desktop/XXXXXXXX/dist/Mac/XXXXXXXX.app/Contents/Resources/app.asar/media.js:19:18) at /Users/nicholasstephan/Desktop/XXXXXXXX/dist/Mac/XXXXXXXX.app/Contents/Resources/app.asar/media.js:52:4 ...

where the media.js, ln 19, being referred to is the const file = fs.createWriteStream(${dir}/${name}); line in the code.

I've tried the solutions offered in about a dozen other similar stackoverflow answers, but none have fixed the problem.

What's going on here?

Thanks.


Solution

  • The built Electron app uses the Asar format. Asar is an archive format (it's really just one big file) though in Electron you are able to read from it as if it were a standard directory.

    I presume (though I have not seen it explicitly documented) that it is not possible to write to an Asar with the fs functions. In any case there are almost certainly more appropriate locations to write data.

    Try writing to a different path. Electron provides a number of useful paths using app.getPath(name) so you could for example write to the userData directory which holds configuration files for your app.