Catching an error in an async function in Node/Express Catching an error in an async function in Node/Express express express

Catching an error in an async function in Node/Express


This has been documented in express error handling doc:

You must catch errors that occur in asynchronous code invoked by route handlers or middleware and pass them to Express for processing. For example:

app.get('/', function (req, res, next) {  setTimeout(function () {    try {      throw new Error('BROKEN')    } catch (err) {      next(err)    }  }, 100)})

The above example uses a try...catch block to catch errors in the asynchronous code and pass them to Express. If the try...catch block were omitted, Express would not catch the error since it is not part of the synchronous handler code.

So, basically you need to try..catch the route. (the examples are basically same, mother of coincidence)


My question is, how the heck do you handle an async error that is outside the scope of a normal request, whether by design ...

You still want to handle errors in asynchronous code, even if it was fired and forgotten by design. Add a try { } catch { } or .catch to every independent task. With asynchronous code, Promises and async / awaithelp you (as they group independent callbacks into tasks, and you can handle errors per task then):

const timer = ms => new Promise(res => setTimeout(res, ms));async function fireAndForgetThis() {  await timer(500);  throw new Error('Async error doesn't cause thread death, because its handled properly')} fireAndForgetThis()   .catch(console.error); // But always "handle" errors

... or through bad code?

Fix bad code.

How do I prevent the thread from dying?

That's not the thing you want to prevent. If an error occurs, and was not handled, your application gets into an unplaned state. Continuing execution might create even more problems. You don't want that. You want to prevent the unhandled rejection / unhandled error itself (by handling it properly).


For sure there are cases you can't handle, e.g. if the connection to the backing database goes down. In that case, NodeJS crashes, causes the monitoring to wake up DevOps that get the database back running. Crashing is also a form of handling the error ;)


If you read this far, and you still want to handle unhandled errors, don't. Okay well, you probably have your reasons, there you go.