google / traceur-compiler

Traceur is a JavaScript.next-to-JavaScript-of-today compiler
Apache License 2.0
8.17k stars 581 forks source link

Logging unhandled promise rejections #1458

Open OliverJAsh opened 9 years ago

OliverJAsh commented 9 years ago

Chrome recently added support for unhandled promises, which means rejections will be logged, whereas before they were silently failing:

image

When using ES6 promises via Traceur in Node.js, I would like unhandled promise rejections to be logged.

Is this a feature request for Node.js? Perhaps the behaviour could be polyfilled inside of Traceur – similar to Q’s promise.done().

UltCombo commented 9 years ago

I believe you could use Bluebird instead of the native/polyfilled Promise, Bluebird naturally logs unhandled rejections and comes with many utility functions as well.

Of course, this behavior would still be nice to have in Node/Traceur.

shirk3y commented 9 years ago

+1 is there currently any way to throw exceptions into await statement? Now, code is silently stopped and nothing is ran after await, and error is silently discarded. Imo, the correct behaviour would be to treat await similar to synchronous code and throw exceptions there.

arv commented 9 years ago

@shirk3y Throwing doesn't do anything useful there. There is no synchronous context that has a try/catch that could catch it. This is one of the problems with promises and async functions.

The best solution for now is to use try/catch in your async function.

async function f() {
  try {
    await Promise.reject(123);
  } catch (ex) {
    console.error(ex);
  }
}
f();
domenic commented 9 years ago

Or more concisely,

async function f() {
  await Promise.reject(123);
}

f().catch(e => console.error(e));
shirk3y commented 9 years ago

This is slightly uncomfortable. await is meant to mimic synchronous code, so I would like to bubble up exceptions to outer scope. Why my code is silently stopping inside async function, without tedious adding try/catch almost everywhere? That is how Python Twisted's inlineCallbacks work. Also libs like StreamlineJS and node-fibers, behaves like this.

domenic commented 9 years ago

Async is not meant to mimic sync code. It provides a convenient syntax for creating promise-returning functions.

On Jan 21, 2015, at 10:16, Mateusz Golewski notifications@github.com<mailto:notifications@github.com> wrote:

This is slightly uncomfortable. await is meant to mimic synchronous code, so I would like to bubble up exceptions to outer scope. Why my code is silently stopping inside async function, without tedious adding try/catch almost everywhere? That is how Python Twisted's inlineCallbackshttp://twistedmatrix.com/documents/10.2.0/api/twisted.internet.defer.inlineCallbacks.html work. Also libs like StreamlineJShttps://github.com/Sage/streamlinejs#exception-handling and node-fibershttps://github.com/laverdet/node-fibers, behaves like this.

Reply to this email directly or view it on GitHubhttps://github.com/google/traceur-compiler/issues/1458#issuecomment-70854929.

shirk3y commented 9 years ago

@domenic i agree. It's not meant to emulate sync code, however it's not straightforward to set errbacks for each promise you await for. In every programming language that supports coroutines I've been using, exceptions are thrown directly in place where coroutine is started. Hypothetically, is it possible to achieve that?

domenic commented 9 years ago

In every programming language that supports coroutines I've been using, exceptions are thrown directly in place where coroutine is started. Hypothetically, is it possible to achieve that?

No, since that code runs in a future event loop turn, and so there is no call stack to catch the error in. I believe this might be the difference between true coroutines (which are emphatically not what async/await provides) and "shallow coroutines."

it's not straightforward to set errbacks for each promise you await for

You should only need to set one per promise chain. In most apps there will be only a few promise chains (roughly, one for the main app, plus one more for each other "async entry points" like event handlers).

johnjbarton commented 9 years ago

In most apps there will be only a few promise chains (roughly, one for the main app, plus one more for each other "async entry points" like event handlers).

In my experience with web browser apps, the first and last part of this statement don't line up. Loading and every user interaction results in async entry points. And a web browser app consists almost exclusively of loading and user interaction. So rather than a "few promise chains", it's more like "all the important logic will be in promise chains".