Talker Talker - 3 months ago 6
Node.js Question

Why doesn't this code catch an error in an 'error' event?

Here is a code:

'use strict';

let fs = require('fs');

module.exports = (fileName, res) => {
fs.createReadStream(fileName)
.pipe(res)
.on('error', err => {
console.log('==========>> ERROR : ' + err.message);
res.statusCode = 500;
res.end('Internal Server Error: 500');
})
.on('end', res.end);
};


When specify wrong "fileName" then server crashes with "ENOENT: no such file or directory" message.

Why doesn't this code catch the error in the .on('error', ...) block?

Thanks!

Answer

At first glance, I think you aren't actually attaching it to read stream (as I figure out you wanted).

See Stream.pipe() documentation:

The readable.pipe() method returns a reference to the destination stream making it possible to set up chains of piped streams

There isn't any error over destination stream, so error callback isn't called.

Try:

module.exports = (fileName, res) => {
    fs.createReadStream(fileName)
        .on('error', err => {
            console.log('==========>> ERROR : ' + err.message);
            res.statusCode = 500;
            res.end('Internal Server Error: 500');
        })
        .on('end', res.end)
        .pipe(res);
};  

...or (clearer and more undestandable):

module.exports = (fileName, res) => {
    var iStream = fs.createReadStream(fileName);
    iStream.on('error', err => {
        console.log('==========>> ERROR : ' + err.message);
        res.statusCode = 500;
        res.end('Internal Server Error: 500');
    }); 
    iStream.on('end', res.end);
    var oStream = iStream.pipe(res) // returns refernce to the output stream (actually res);
};

...on the other hand, I'm not sure if stream will actually be created if file doesn't exists.

Probably fs.createReadStream() itself would throw an error before actually creating the stream so, for this reason, you should probably enclose it in a try {...} catch(){...} block.

Anyway I'm not sure about that. It would be more handy (from the coding point of view) if createReadStream() creates the stream before opening the file and then throws the error, (over the stream) if the file actually doesn't exists. But this should be investigated or tested before.