Reputation: 1035
So, the trivial thing. All we know that Express has built-in default error handler that expect four arguments (err, req, res, next) to handle "synchronous exceptions" like ReferenceError, TypeError, etc:
UPDATE: this question is Express-specific, not about how to catch unhandled exceptions/etc. I want to know how in the first code block Express can handle user-defined exception. Second example with async. exception doesn't directly belongs to this question.
const express = require('express')();
express.all('*', (req, res) => {
throw new Error('my own error');
res
.send('okay?');
});
express.use((err, req, res, next) => {
console.error(err.stack);
res
.status(503)
.send('Express is still up and running');
}).listen(3000);
But not this:
const express = require('express')();
express.all('*', (req, res) => {
process.nextTick(() => {
throw new Error('my own error');
});
res
.send('okay?');
});
express.use((err, req, res, next) => {
console.error(err.stack);
res
.status(503)
.send('Won\'t be executed');
}).listen(3000);
But I'm curious about the realization of this handler.
I can't find anything like
process.on('uncaughtException'...
or domains/Promises/cluster.
Maybe I miss something.
Can anyone clarify?
Upvotes: 1
Views: 766
Reputation: 30481
There is a catch-all kind of block in Express's router that gets executed:
try {
fn(req, res, next);
} catch (err) {
next(err);
}
So in this block all exceptions are catched and translated to next()
function calls with error parameter set to match the exception.
In more detail, when a request arrives to express:
app.handle()
is called, which then determines router and calls router.handle()
router.handle()
processes through layers and eventually matches your handler registered with express.all('*', ...)
signaturehandle_request
(inside router's internal Layer module) calls your handler function as specified in the above try-catch block, effectively catching all possible exceptions and translating them into next calls.Upvotes: 1