admin管理员组

文章数量:1400599

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 unfortable.

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 unfortable.

Share Improve this question asked Jan 10, 2017 at 12:54 MentorMentor 1,00311 silver badges21 bronze badges 7
  • What do you mean by "every promise you use"? You only need to catch errors at the end of the chain. Also, what do you mean by "swallowing"? If you want to prevent that, what should happen with the errors instead? – Bergi Commented Jan 11, 2017 at 2:14
  • When using a lot of promises putting .catch after every chain can be exhausting and not at all DRY. Edit: With swallowing I mean that no error lines or details are provided. The errors instead should by default have a handler associated, in my case I wanted them to show up in my node console. – Mentor Commented Jan 11, 2017 at 13:11
  • 1 There are other ways to make such code dry than to omit .catch(function(e) {…}) that is the same everywhere. Where are your many chains started? Event handlers, route handlers? Then define a wrapper function that installs the handler and treats the returned promises appropriately. If you could post your code, I'd be able to write a more specific answer. – Bergi Commented Jan 11, 2017 at 15:03
  • 1 Writing code without any .catch() handlers is simply just bad code. You don't globally diagnose missing reject handlers. It's just not how you write good code. You don't have to put a .catch() on every promise. You should have one on every promise chain though as I explain the logic for in my answer. If you're the one who downvoted my answer, then I apologize for giving you the proper programming answer to your situation. You can't do it the way you're asking so I've described how you should handle rejections. If you don't like that, then I can delete my answer. – jfriend00 Commented Jan 11, 2017 at 18:36
  • 1 @jfriend00, didn't notice you mented there. I did not downvote you, but disagree that it is bad code. My purpose was simply to have a default error handler and in that prevent a lot of identical .catches. Where errors are relevant to program function or user experience I have .catches handle the error. In some cases however I simply want the error logged (either to a console, log file or error db). There is nothing bad about this :) – Mentor Commented Aug 28, 2017 at 10:30
 |  Show 2 more ments

2 Answers 2

Reset to default 6

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 ply 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.

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 )
} )

本文标签: javascriptPrevent ES6 promises from swallowing errors (without using catch)Stack Overflow