简体   繁体   中英

ExpressJs send response with error inside middleware

I can't understand why my ExpressJs app is crashing sending res.status(401) inside a middleware.

Let's say my start.js has:

app.use(middlewares.timestampValidator());

and the middleware is declared as follow:

 timestampValidator: () => { return (req, res, next) => { [...] if(error) { res.status(401).json(new ServerResponse()); } else { next(); } } }

When the error is -successfully- sent to the client the server crashes with this error:

node:internal/process/promises:246 triggerUncaughtException(err, true /* fromPromise */); ^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async > function without a catch block, or by rejecting a promise which was not handled with > >.catch(). The promise rejected with the reason "false".] { code: 'ERR_UNHANDLED_REJECTION' }

But the functions is not async. I tried calling next('error'); after sending status 401 but the app continues to routes and then the response can't be send to client because already sent.

I got the same thing in my nodejs application. My middleware was crashing in the application, and after some time of the crash, the unhandlesPromiseRejectionException was raised. The middleware is not async, but this crash is stopping the execution of the code (if try catch is not used to handle it), thereby terminating the entire process and then after a while the exception is raised.

If you notice the time of error receiving on the client, you could see that you get the error on the client sooner and the PromiseException gets raised later. I would ask you to check, if the error you get on the client, is that a timeout error, or the error code that you have thrown

I think Express just raises unhandled exception in middlewares as unhandledPromiseRejection By default as it is a break in its api hittin process which is asynchronous by default. EVen though your middleware is synchronous, but it is placed in an asynchronous process of an API route, and if anything crashes in it which is not handled, it will raise an UnhandledPromiseRejectionException as it is a crash in an asynchronous process.

Try to think of it as this: -

public async randomeFUnction()
{
syncFUnction1()
syncFUnction2()
await asyncFUnction()
}

now if syncFunction1 crashes, it will still be an unhandledPromiseException, although the main stacktrace leads to a sunchronous method, but essentially, randomeFUnction is the one which has failed, which is an async function.

I would suggest to use try catch to prevent a formal crash rather than an If condition.

Let me know if it helps.

If you are using an error handling middleware, the error shoulde be passed to the error handler. Which prevents 'UnhandledPromiseRejection'.

if(error) {
    next(new ServerResponse());
}
else {
   // continue ... 
}

If you are not using an error handling middleware throw the error ( new ServerResponse() ) in a try/catch block

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM