The code as written in the answer should work just fine, since the code is synchronous - that is, it's not async
and it doesn't hand next()
off to a callback anywhere. Per the Express.js docs (emphasis mine):
Errors that occur in synchronous code inside route handlers and middleware require no extra work. If synchronous code throws an error, then Express will catch and process it.
So in synchronous middlewares and handlers, just throw the error, Express will catch it and pass it to the error middleware.
For asynchronous middlewares, you need to pass the error object to the next()
function without throwing it. The example from the docs applies just as well to middlewares as it does to route handlers (which are in fact also middleware), to adapt it to your example:
function SomeMiddleware(req, res, next) {
user.checkRealOrSomethingAsync(isReal => {
if(!isReal) {
// Note: Pass the exception, do not throw it!
next(new HttpException(401, "Tough luck buddy"))
}
next()
})
}
Note that, as per the Express docs, this means you must catch any errors thrown in async middlewares or routes and pass them into next()
.
However! Starting in Express 5, you don't need to catch errors thrown within async
methods, the error will be propagated as normal without you doing anything. express-async-errors package will patch Express.js 4 to work similarly. Note this only applies to errors at the "top level" of the async function - if you're mixing async and callbacks, you'll still have to catch errors inside the callbacks.
next()
in the error case at all, because it will instead throw the exception while evaluating the arguments and exit before it can call thenext()
function. – Predisposition