4

I have a promise and I would like an exception to be thrown if the promise is rejected. I tried this:

var p = new Promise( (resolve, reject) => {
  reject ("Error!");
} );

p.then(value => {console.log(value);});

but I get a DeprecationWarning:

(node:44056) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error!
(node:44056) DeprecationWarning: 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.

What is the correct way to throw an error (so that the program is terminated with a stack trace) if the promise is rejected?

I already tried to insert a throw statement in a catch clause, but this again produces a DeprecationWarning as before. In fact (after some reading) I understand that a throw in a catch produce another call to the reject callback.

Emanuele Paolini
  • 9,912
  • 3
  • 38
  • 64

3 Answers3

2

You can catch unhandledRejection events to log an stack trace, provided that you reject using a proper Error:

var p = new Promise( (resolve, reject) => {
  reject( Error("Error!") );
} );

p.then(value => {console.log(value);});

process.on('unhandledRejection', e => {
  console.error(e);
});
robertklep
  • 198,204
  • 35
  • 394
  • 381
2

…so that the program is terminated with a stack trace if the promise is rejected?

That's exactly what unhandled promise rejections will do in the future, as the "deprecation" warning is telling you. See these pull requests for what they plan to do, as well as the general discussion.

For now, you can listen to unhandledRejection events to do this:

process.on('unhandledRejection', err => {
  console.error(err); // or err.stack and err.message or whatever you want
  process.exit(1);
});
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • So I could safely ignore the warning and keep the code like it is? This is actually the correct way to obtain what I need. – Emanuele Paolini Aug 19 '17 at 13:00
  • @EmanuelePaolini The deprecation warning, yes. The unhandled rejection warning, no - you should *not* write code that doesn't handle errors. It would have been better to write `p.then(console.log, console.error);` which handles the error by logging it (and then terminating as usual). – Bergi Aug 19 '17 at 13:25
  • First days with node.js (coming from python) so I could be wrong. But I would catch exceptions only if I can deal with them. If I have an unexpected exception (maybe a programming error) I think the best to do is leave it go up to the user... I see no reason to log the exception since it would be logged anyway. – Emanuele Paolini Aug 19 '17 at 14:09
  • 1
    @EmanuelePaolini The problem is that Promises (and JS in general) cannot easily distinguish (unexpected) programmer from (expected) operational errors. There's no conditional catch clause (like `except X:` in Python), you always need to catch all errors and distinguish them explicitly. My guess for not having this "leave it go up to the user" functionality is that Node.js was built primarily for server applications not interactive ones. And promise rejections working different than exceptions is imo an unfortunate design mistake, but changing it now is hard. – Bergi Aug 19 '17 at 14:49
0

You are getting DeprecationWarning because adding catch block while resolving promise is going to be mandatory.

You can throw the error from inside catch block, this way your program will be terminated with the error's stack trace, like:

p.then( value => console.log(value) ).catch( e => { throw e });

Else you can catch the error and do some stuff while not terminating the process, like:

p.then( value => console.log(value) ).catch( e => { console.log('got an error, but the process is not terminated.') });
Raghav Garg
  • 3,601
  • 2
  • 23
  • 32