Reputation: 43437
For example I just tried to catch ENOENT
by naively doing this:
try {
res.sendFile(path);
} catch (e) {
if (e.code === 'ENOENT') {
res.send('placeholder');
} else { throw e; }
}
This doesn't work!
I know that the right way is to use the error callback of sendFile
, but it's really surprising and bad for me that the fundamental language feature of exceptions doesn't work here.
I guess maybe express itself is doing the catching. And they want to not have the errors kill the server so quickly. It's understandable.
But I just get this lame message:
Error: ENOENT: no such file or directory, stat '<file>'
at Error (native)
Not great.
Upvotes: 1
Views: 95
Reputation: 10497
Generally speaking, you want to avoid using exceptions to control program flow.
Also, since you're apparently programming this in Node.js, you pass a callback function to keep Node running asynchronously. Node.js is not multithreaded, because JavaScript is not multithreaded, so it cannot have more than one thing going on at a time. That means that if your code is hung up handling an exception, nothing else is happening. And Exceptions are expensive. Doing expensive cleanup in a single-threaded server-side application will harm performance and scalability. Nor is JavaScript itself magically asynchronous. It's asynchronous only if you use callback functions to loosen it up.
So when you pass a callback function to res.send, that function gets called asynchronously when the res.send function finishes (or exits without finishing due to an error), without the overhead of a thrown exception. Thus, if you want to handle errors, passing a callback method is the way to do it.
Upvotes: 1
Reputation: 911
Its because of the Asynchronous nature of Javascript that the code will not catch the exception you are throwing. The res.sendFile
is executed outside the scope of try
block and the try
block execution will be over after the call to res.sendFile
method.
That is the reason why it is always advised to use the callback mechanism with err object as the first argument to the callback and you can check that first before proceeding
res.sendFile(path, function (e) {
// check the error first
// then procedd with the execution
});
Upvotes: 2
Reputation: 623
Due to documentation res.sendFile
is async function, so try/catch
won't work in this case. If you want to handle res.sendFile
result you must pass callback
as last argument.
res.sendFile(path, function (e) {
if (e) {
if (e.code === 'ENOENT') {
res.send('placeholder');
} else {
throw e;
}
}
});
Upvotes: 3