Mentor
Mentor

Reputation: 1003

Prevent ES6 promises from swallowing errors (without using .catch)

I do not want to type .catch for every promise I use. Without doing this errors caused by promises are supremely unhelpful.

Using an entire library like bluebird purely for this purpose makes me uncomfortable.

Upvotes: 5

Views: 3544

Answers (2)

Estus Flask
Estus Flask

Reputation: 223288

For error tracking during development, V8 (recent Node.js and Chrome versions) already has got unhandledRejection (Node.js) and unhandledrejection (Chrome) event listener by default, which results in UnhandledPromiseRejectionWarning warning in Node.js and Uncaught (in promise) error in Chrome.

Deprecation warning in Node 7 states that this will be changed in future Node.js versions:

Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Error handling in promises is not optional and should be treated on par with try...catch. Every promise that has a chance to be rejected should be chained with catch. And in the case of async...await or co, .catch is identical to try...catch.

If the error is supposed to be ignored, it has to be explicitly caught. If error handling needs to be consistent across the app and comply to log levels, this may be provided by design. E.g. with conventional debug package:

const debug = require('debug');

function catchFn(err, ns = 'myapp:caughtPromises') {
    debug(ns)(err);
}

function catchPromise(promise, ns) {
    promise.catch(err => catchFn(err, ns));
    return promise;
}

...

try {
  await promise;
} catch (err) {
  catchFn(err);
}

// or
catchPromise(promise);

// or
promise.catch(catchFn);

catchFn can be extended to use third-party logging service as well.

Upvotes: 6

Mentor
Mentor

Reputation: 1003

Add a handler to your process for unhandled rejections. You can handle them once like that instead of copy-pasting .catch statements all the time.

process.on( 'unhandledRejection', ( error, promise ) => {
    console.log( 'UPR: ' + promise + ' with ' + error )
    console.log( error.stack )
} )

Upvotes: 1

Related Questions