0

I need a very simple pattern for a catch-all of async/Promise errors; the normal pattern of:

app.use(function (err, req, res, next) {
  ...
});

does not handle async errors, and I can't find any working pattern anywhere.

What I did find is very limited:

process.on('unhandledRejection', function (err, p) {
  ...
});

It's limited because I don't have a req object to do some logging/retrospection with, and I don't have a res object to shape my response.

What might be a working pattern for a catch-all that catches async/Promise exceptions?

Ofer Zelig
  • 17,068
  • 9
  • 59
  • 93
  • 1
    Take a look at how https://github.com/express-promise-router/express-promise-router or https://github.com/blakeembrey/async-middleware deal with it. – robertklep Jul 24 '17 at 17:17
  • Have a look at [this](https://stackoverflow.com/a/40679642/1048572) or [that question](https://stackoverflow.com/q/41349331/1048572) on how to use promise-returning functions in express – Bergi Jul 24 '17 at 18:52
  • @Bergi both answers don't provide a catch-all handler. – Ofer Zelig Jul 25 '17 at 12:48
  • @OferZelig The answers provide the way to write express middlewares with promises so that you can *use* the default express catch-all handler. They work just fine with asynchronous errors, you just need to trigger the error callback. – Bergi Jul 25 '17 at 13:10
  • @Bergi but that's my point, I don't want to explicitly trigger a `catch` etc. I want unplanned errors to just bubble up to Express and let it log them and nicely return a friendly error to the user, from one centralized place. – Ofer Zelig Jul 26 '17 at 19:34
  • @robertklep they look interesting, I'll try and let you know. Thanks! – Ofer Zelig Jul 26 '17 at 19:35
  • @OferZelig The answers provide ways to *implicitly* trigger the `catch`. There's no way around this. A "catch-all", whether it's `unhandledRejection`s or `uncaughtException`s, never works for a specific request. You can only show friendly error messages for *planned* errors. – Bergi Jul 26 '17 at 19:38
  • @robertklep apparently, express-promise-router did quite a good and clean job. Thanks! Do you want to submit it as an answer? – Ofer Zelig Aug 23 '17 at 18:07

1 Answers1

0

If you are using ES promise, you could use the Promise.all clause like so:

var promise1 = Promise.resolve(3);
var promise2 = new Promise(function(){throw "some exception";});
var promise3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3])
  .catch(function(err) {
    // log that I have an error, return the entire array;
    alert('A promise failed to resolve', err);
    return arrayOfPromises;
  })
  .then(function(values) {
    alert(values);
  });

The idea here is to create a service or a single place where you can send the array of promises, and do a generic "catch" and "then" handling. I think you can even get the exceptions list by iterating over the promises as you wish.

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

Henry Aloni
  • 617
  • 7
  • 24
  • This is a borderline [link-only answer](//meta.stackexchange.com/q/8231). You should expand your answer to include as much information here, and use the link only for reference. – Blue Feb 06 '18 at 04:33
  • This doesn't answer what I need. I wanted an app-level catch-all mechanism. – Ofer Zelig Feb 07 '18 at 09:05