Re: [whatwg] An API for unhandled promise rejections

2015-06-17 Thread Domenic Denicola
Yes, see:

- https://lists.w3.org/Archives/Public/public-whatwg-archive/2015May/0051.html
- https://github.com/domenic/unhandled-rejections-browser-spec
- https://codereview.chromium.org/1179113007/

> -Original Message-
> From: Conrad Irwin [mailto:conrad.ir...@gmail.com]
> Sent: Wednesday, June 17, 2015 14:40
> To: wha...@whatwg.org; Domenic Denicola
> Subject: Re: [whatwg] An API for unhandled promise rejections
> 
> Hi Domenic,
> 
> Sorry to re-open an old thread; but this is important to me :).
> 
> Do you know if there’s been any progress on getting this behavior
> standardized (or even better, implemented)?
> 
> Conrad


Re: [whatwg] An API for unhandled promise rejections

2015-05-19 Thread Jonas Sicking
On Tue, May 19, 2015 at 2:07 PM, Domenic Denicola  wrote:
>> An API being proposed on a mailing list such as this one?
>
> The API is already proposed (see the rest of this thread).

Ah, sorry, I misunderstood your earlier email to mean that you were
intending to experiment with the API as well.

/ Jonas


Re: [whatwg] An API for unhandled promise rejections

2015-05-19 Thread Domenic Denicola
From: Jonas Sicking [mailto:jo...@sicking.cc]

> An API being proposed on a mailing list such as this one?

The API is already proposed (see the rest of this thread). The exact timing is 
tricky to figure out without a working implementation to play with, compare to 
real-world code, tweak, adjust, write and run test cases against. I could 
conjecture a timing without that information, but I'd prefer to gather it first 
before stating anything even halfway definitive.


Re: [whatwg] An API for unhandled promise rejections

2015-05-19 Thread Jonas Sicking
On Tue, May 19, 2015 at 2:04 PM, Domenic Denicola  wrote:
> From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Jonas 
> Sicking
>
>> That sounds hard to provide feedback on...
>
> What working mode would you prefer?

An API being proposed on a mailing list such as this one?

/ Jonas


Re: [whatwg] An API for unhandled promise rejections

2015-05-19 Thread Elliott Sprehn
On Tue, May 19, 2015 at 2:02 PM, Jonas Sicking  wrote:

> On Tue, May 19, 2015 at 1:57 PM, Domenic Denicola  wrote:
> >> It's hard to say what "this" you're talking about implementing in
> Chrome in
> >> terms of the task-queueing behavior.  Is that something you just haven't
> >> decided on yet?
> >
> > Yeah, I think this will be something that gets nailed down more during
> implementation and writing of test cases.
>
> That sounds hard to provide feedback on...
>
>
Note that of the options mentioned above, there's no way to have "a task
after all tasks" or a "a microtask after all microtasks" because both are
loops so there's no concept of "after all".

At best it seems either this posts a task or a microtask.

- E


Re: [whatwg] An API for unhandled promise rejections

2015-05-19 Thread Domenic Denicola
From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Jonas Sicking

> That sounds hard to provide feedback on...

What working mode would you prefer?


Re: [whatwg] An API for unhandled promise rejections

2015-05-19 Thread Jonas Sicking
On Tue, May 19, 2015 at 1:57 PM, Domenic Denicola  wrote:
>> It's hard to say what "this" you're talking about implementing in Chrome in
>> terms of the task-queueing behavior.  Is that something you just haven't
>> decided on yet?
>
> Yeah, I think this will be something that gets nailed down more during 
> implementation and writing of test cases.

That sounds hard to provide feedback on...

/ Jonas


Re: [whatwg] An API for unhandled promise rejections

2015-05-19 Thread Domenic Denicola
From: Boris Zbarsky [mailto:bzbar...@mit.edu]

> We (Mozilla) support having something here.

Great! Thanks for your reply. And sorry for the lack of the specifics. We'll 
work on nailing something down (spec-wise) as we implement, and of course far 
ahead of any shipping. I'll reply when I get a repo up.

>  Not making the error event
> even more complicated than it already is makes sense.

That's good feedback given the internal split of opinions. Hopefully enough to 
tip the balance. 

> Presumably
> whatever the new events are would also get propagated from worker global
> scope to worker?

Agreed.

> Event names in the web platform are typically lowercase, not camelCase.

For sure.

> It's hard to say what "this" you're talking about implementing in Chrome in
> terms of the task-queueing behavior.  Is that something you just haven't
> decided on yet?

Yeah, I think this will be something that gets nailed down more during 
implementation and writing of test cases.


Re: [whatwg] An API for unhandled promise rejections

2015-05-19 Thread Boris Zbarsky

On 5/18/15 6:49 PM, Domenic Denicola wrote:

Ping. We're considering implementing this in Chrome and it would be helpful to 
get a sense if other vendors support this.


We (Mozilla) support having something here.  Not making the error event 
even more complicated than it already is makes sense.  Presumably 
whatever the new events are would also get propagated from worker global 
scope to worker?


Event names in the web platform are typically lowercase, not camelCase.

It's hard to say what "this" you're talking about implementing in Chrome 
in terms of the task-queueing behavior.  Is that something you just 
haven't decided on yet?


Past that, I'm not sure we have any particular thoughts on the details 
here so far...


-Boris


Re: [whatwg] An API for unhandled promise rejections

2015-05-18 Thread Domenic Denicola
The OP proposal.

> -Original Message-
> From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of
> Elliott Sprehn
> Sent: Monday, May 18, 2015 19:23
> To: Domenic Denicola
> Cc: WHATWG; Boris Zbarsky; Brian Terlson
> Subject: Re: [whatwg] An API for unhandled promise rejections
> 
> What of the many things in that email are you considering?
> 
> On Mon, May 18, 2015 at 3:49 PM, Domenic Denicola 
> wrote:
> 
> > Ping. We're considering implementing this in Chrome and it would be
> > helpful to get a sense if other vendors support this.
> >
> > > -Original Message-
> > > From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of
> > > Domenic Denicola
> > > Sent: Monday, February 9, 2015 20:45
> > > To: WHATWG
> > > Cc: Petka Antonov
> > > Subject: Re: [whatwg] An API for unhandled promise rejections
> > >
> > > An update on this: although the conversation somewhat fizzled here,
> > > in
> > io.js
> > > (Node.js fork) something very similar is landing and I'm trying to
> > > guide
> > it
> > > toward being reasonably compatible with browsers [1]. Additionally
> > several
> > > promise libraries have implemented similar hooks (see [2] and links
> > > in
> > the
> > > comments; also of interest is the analysis of how promise-using
> > libraries use
> > > these hooks).
> > >
> > > The community largely settled on
> > > unhandledRejection/rejectionHandled,
> > > instead of hijacking the error event like the original post below
> > proposes.
> > > Which is not to say that we have to respect that in browsers, but
> > > it's a
> > data
> > > point to consider.
> > >
> > > One interesting question that came up is the exact timing of the
> > > unhandledRejection event. In my proto-spec at [3] I proposed queuing
> > > a separate notify-rejected task for each rejection, largely because
> > > it
> > seemed
> > > the easiest thing to spec. We now have some experience from the field.
> > The
> > > implementation at [1] considered a few approaches and cycled through
> > > implementing some subset of them to make a progressively-larger set
> > > of tests pass:
> > >
> > > - Queue a single task
> > > - Queue a separate task per rejection (as in proto-spec)
> > > - Queue a microtask that occurs after all other microtasks
> > > - Queue a task that occurs after all other tasks
> > >
> > > Hopefully Petka, CC'ed, can correct me if I misstated these and fill
> > > in
> > any
> > > details I missed.
> > >
> > > In general I am in favor of pushing off notification as long as
> > > possible
> > to give
> > > more time for the rejection to potentially become handled (and thus
> > > decrease false positives). From this perspective either separate
> > > task per rejection or after-all-others task seems good. I was hoping
> > > to get a web platform perspective on what sounds good and would be
> implementable?
> > > For example I think the after-all-others-task can be specced with a
> > > new
> > task
> > > source that HTML mandates is drained after all others, right?
> > >
> > > Anyway, I mostly just wanted to give people an update and show that
> > > we're prototyping this in io.js. Hopefully the interchange of ideas
> > > here can
> > help
> > > push the progress in browsers too.
> > >
> > >
> > > [1]: https://github.com/iojs/io.js/pull/758
> > > [2]: https://gist.github.com/benjamingr/0237932cee84712951a2
> > > [3]:
> > > https://gist.github.com/domenic/9b40029f59f29b822f3b#promise-error-
> > > handling-hooks-rough-spec-algorithm
> > >
> > >
> > > -Original Message-
> > > From: Domenic Denicola
> > > Sent: Friday, September 12, 2014 14:34
> > > To: WHATWG
> > > Subject: An API for unhandled promise rejections
> > >
> > > ## Problem
> > >
> > > A common desire in web programming is to log any uncaught exceptions
> > > back to the server. The typical method for doing this is
> > >
> > > window.onerror = (message, url, line, column, error) => {
> > >   // log `error` back to the server
> > > };
> > >
> > > When programming asynchronously with promises, asynchronous
> > > exce

Re: [whatwg] An API for unhandled promise rejections

2015-05-18 Thread Elliott Sprehn
What of the many things in that email are you considering?

On Mon, May 18, 2015 at 3:49 PM, Domenic Denicola  wrote:

> Ping. We're considering implementing this in Chrome and it would be
> helpful to get a sense if other vendors support this.
>
> > -Original Message-
> > From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of
> > Domenic Denicola
> > Sent: Monday, February 9, 2015 20:45
> > To: WHATWG
> > Cc: Petka Antonov
> > Subject: Re: [whatwg] An API for unhandled promise rejections
> >
> > An update on this: although the conversation somewhat fizzled here, in
> io.js
> > (Node.js fork) something very similar is landing and I'm trying to guide
> it
> > toward being reasonably compatible with browsers [1]. Additionally
> several
> > promise libraries have implemented similar hooks (see [2] and links in
> the
> > comments; also of interest is the analysis of how promise-using
> libraries use
> > these hooks).
> >
> > The community largely settled on unhandledRejection/rejectionHandled,
> > instead of hijacking the error event like the original post below
> proposes.
> > Which is not to say that we have to respect that in browsers, but it's a
> data
> > point to consider.
> >
> > One interesting question that came up is the exact timing of the
> > unhandledRejection event. In my proto-spec at [3] I proposed queuing a
> > separate notify-rejected task for each rejection, largely because it
> seemed
> > the easiest thing to spec. We now have some experience from the field.
> The
> > implementation at [1] considered a few approaches and cycled through
> > implementing some subset of them to make a progressively-larger set of
> > tests pass:
> >
> > - Queue a single task
> > - Queue a separate task per rejection (as in proto-spec)
> > - Queue a microtask that occurs after all other microtasks
> > - Queue a task that occurs after all other tasks
> >
> > Hopefully Petka, CC'ed, can correct me if I misstated these and fill in
> any
> > details I missed.
> >
> > In general I am in favor of pushing off notification as long as possible
> to give
> > more time for the rejection to potentially become handled (and thus
> > decrease false positives). From this perspective either separate task per
> > rejection or after-all-others task seems good. I was hoping to get a web
> > platform perspective on what sounds good and would be implementable?
> > For example I think the after-all-others-task can be specced with a new
> task
> > source that HTML mandates is drained after all others, right?
> >
> > Anyway, I mostly just wanted to give people an update and show that we're
> > prototyping this in io.js. Hopefully the interchange of ideas here can
> help
> > push the progress in browsers too.
> >
> >
> > [1]: https://github.com/iojs/io.js/pull/758
> > [2]: https://gist.github.com/benjamingr/0237932cee84712951a2
> > [3]: https://gist.github.com/domenic/9b40029f59f29b822f3b#promise-error-
> > handling-hooks-rough-spec-algorithm
> >
> >
> > -Original Message-
> > From: Domenic Denicola
> > Sent: Friday, September 12, 2014 14:34
> > To: WHATWG
> > Subject: An API for unhandled promise rejections
> >
> > ## Problem
> >
> > A common desire in web programming is to log any uncaught exceptions
> > back to the server. The typical method for doing this is
> >
> > window.onerror = (message, url, line, column, error) => {
> >   // log `error` back to the server
> > };
> >
> > When programming asynchronously with promises, asynchronous
> > exceptions are encapsulated as _rejected promises_. They can be caught
> > and handled with `promise.catch(err => ...)`, and propagate up through an
> > "asynchronous call stack" (i.e. a promise chain) in a similar manner to
> > synchronous errors.
> >
> > However, for promises, there is no notion of the "top-level" of the
> promise
> > chain at which the rejection is known to be unhandled. Promises are
> > inherently temporal, and at any time code that has access to a given
> promise
> > could handle the rejection it encapsulates. Thus, unlike with synchronous
> > code, there is not an ever-growing list of unhandled exceptions: instead,
> > there is a growing and shrinking list of currently-unhandled rejections.
> >
> > For developers to be able to debug promises effectively, this live list
> of
> > currently-unhandled reject

Re: [whatwg] An API for unhandled promise rejections

2015-05-18 Thread Domenic Denicola
Ping. We're considering implementing this in Chrome and it would be helpful to 
get a sense if other vendors support this.

> -Original Message-
> From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of
> Domenic Denicola
> Sent: Monday, February 9, 2015 20:45
> To: WHATWG
> Cc: Petka Antonov
> Subject: Re: [whatwg] An API for unhandled promise rejections
> 
> An update on this: although the conversation somewhat fizzled here, in io.js
> (Node.js fork) something very similar is landing and I'm trying to guide it
> toward being reasonably compatible with browsers [1]. Additionally several
> promise libraries have implemented similar hooks (see [2] and links in the
> comments; also of interest is the analysis of how promise-using libraries use
> these hooks).
> 
> The community largely settled on unhandledRejection/rejectionHandled,
> instead of hijacking the error event like the original post below proposes.
> Which is not to say that we have to respect that in browsers, but it's a data
> point to consider.
> 
> One interesting question that came up is the exact timing of the
> unhandledRejection event. In my proto-spec at [3] I proposed queuing a
> separate notify-rejected task for each rejection, largely because it seemed
> the easiest thing to spec. We now have some experience from the field. The
> implementation at [1] considered a few approaches and cycled through
> implementing some subset of them to make a progressively-larger set of
> tests pass:
> 
> - Queue a single task
> - Queue a separate task per rejection (as in proto-spec)
> - Queue a microtask that occurs after all other microtasks
> - Queue a task that occurs after all other tasks
> 
> Hopefully Petka, CC'ed, can correct me if I misstated these and fill in any
> details I missed.
> 
> In general I am in favor of pushing off notification as long as possible to 
> give
> more time for the rejection to potentially become handled (and thus
> decrease false positives). From this perspective either separate task per
> rejection or after-all-others task seems good. I was hoping to get a web
> platform perspective on what sounds good and would be implementable?
> For example I think the after-all-others-task can be specced with a new task
> source that HTML mandates is drained after all others, right?
> 
> Anyway, I mostly just wanted to give people an update and show that we're
> prototyping this in io.js. Hopefully the interchange of ideas here can help
> push the progress in browsers too.
> 
> 
> [1]: https://github.com/iojs/io.js/pull/758
> [2]: https://gist.github.com/benjamingr/0237932cee84712951a2
> [3]: https://gist.github.com/domenic/9b40029f59f29b822f3b#promise-error-
> handling-hooks-rough-spec-algorithm
> 
> 
> -Original Message-
> From: Domenic Denicola
> Sent: Friday, September 12, 2014 14:34
> To: WHATWG
> Subject: An API for unhandled promise rejections
> 
> ## Problem
> 
> A common desire in web programming is to log any uncaught exceptions
> back to the server. The typical method for doing this is
> 
> window.onerror = (message, url, line, column, error) => {
>   // log `error` back to the server
> };
> 
> When programming asynchronously with promises, asynchronous
> exceptions are encapsulated as _rejected promises_. They can be caught
> and handled with `promise.catch(err => ...)`, and propagate up through an
> "asynchronous call stack" (i.e. a promise chain) in a similar manner to
> synchronous errors.
> 
> However, for promises, there is no notion of the "top-level" of the promise
> chain at which the rejection is known to be unhandled. Promises are
> inherently temporal, and at any time code that has access to a given promise
> could handle the rejection it encapsulates. Thus, unlike with synchronous
> code, there is not an ever-growing list of unhandled exceptions: instead,
> there is a growing and shrinking list of currently-unhandled rejections.
> 
> For developers to be able to debug promises effectively, this live list of
> currently-unhandled rejections certainly needs to be exposed via developer
> tools, similar to how devtools exposes the ever-growing list of unhandled
> exceptions (via console output). However, developer tools are not sufficient
> to satisfy the telemetry use case, i.e. the use case which is currently 
> handled
> via `window.onerror` for synchronous code.
> 
> ## Proposed Solution
> 
> We propose that
> 
> 1. `window.onerror` be extended to handle the rejected-promise use case,
> notifying about any promises that, "at the end of the task queue", contain
> rejections that are not yet handled; and 2. A new hoo

Re: [whatwg] An API for unhandled promise rejections

2015-02-09 Thread Boris Zbarsky

On 2/9/15 8:45 PM, Domenic Denicola wrote:

- Queue a task that occurs after all other tasks


On many web pages, this would effectively mean "never" because they post 
tasks all the time...


-Boris


Re: [whatwg] An API for unhandled promise rejections

2015-02-09 Thread Domenic Denicola
An update on this: although the conversation somewhat fizzled here, in io.js 
(Node.js fork) something very similar is landing and I'm trying to guide it 
toward being reasonably compatible with browsers [1]. Additionally several 
promise libraries have implemented similar hooks (see [2] and links in the 
comments; also of interest is the analysis of how promise-using libraries use 
these hooks).

The community largely settled on unhandledRejection/rejectionHandled, instead 
of hijacking the error event like the original post below proposes. Which is 
not to say that we have to respect that in browsers, but it's a data point to 
consider.

One interesting question that came up is the exact timing of the 
unhandledRejection event. In my proto-spec at [3] I proposed queuing a separate 
notify-rejected task for each rejection, largely because it seemed the easiest 
thing to spec. We now have some experience from the field. The implementation 
at [1] considered a few approaches and cycled through implementing some subset 
of them to make a progressively-larger set of tests pass:

- Queue a single task
- Queue a separate task per rejection (as in proto-spec)
- Queue a microtask that occurs after all other microtasks
- Queue a task that occurs after all other tasks

Hopefully Petka, CC'ed, can correct me if I misstated these and fill in any 
details I missed.

In general I am in favor of pushing off notification as long as possible to 
give more time for the rejection to potentially become handled (and thus 
decrease false positives). From this perspective either separate task per 
rejection or after-all-others task seems good. I was hoping to get a web 
platform perspective on what sounds good and would be implementable? For 
example I think the after-all-others-task can be specced with a new task source 
that HTML mandates is drained after all others, right?

Anyway, I mostly just wanted to give people an update and show that we're 
prototyping this in io.js. Hopefully the interchange of ideas here can help 
push the progress in browsers too.


[1]: https://github.com/iojs/io.js/pull/758
[2]: https://gist.github.com/benjamingr/0237932cee84712951a2
[3]: 
https://gist.github.com/domenic/9b40029f59f29b822f3b#promise-error-handling-hooks-rough-spec-algorithm


-Original Message-
From: Domenic Denicola 
Sent: Friday, September 12, 2014 14:34
To: WHATWG
Subject: An API for unhandled promise rejections

## Problem

A common desire in web programming is to log any uncaught exceptions back to 
the server. The typical method for doing this is

window.onerror = (message, url, line, column, error) => {
  // log `error` back to the server
};

When programming asynchronously with promises, asynchronous exceptions are 
encapsulated as _rejected promises_. They can be caught and handled with 
`promise.catch(err => ...)`, and propagate up through an "asynchronous call 
stack" (i.e. a promise chain) in a similar manner to synchronous errors.

However, for promises, there is no notion of the "top-level" of the promise 
chain at which the rejection is known to be unhandled. Promises are inherently 
temporal, and at any time code that has access to a given promise could handle 
the rejection it encapsulates. Thus, unlike with synchronous code, there is not 
an ever-growing list of unhandled exceptions: instead, there is a growing and 
shrinking list of currently-unhandled rejections.

For developers to be able to debug promises effectively, this live list of 
currently-unhandled rejections certainly needs to be exposed via developer 
tools, similar to how devtools exposes the ever-growing list of unhandled 
exceptions (via console output). However, developer tools are not sufficient to 
satisfy the telemetry use case, i.e. the use case which is currently handled 
via `window.onerror` for synchronous code.

## Proposed Solution

We propose that

1. `window.onerror` be extended to handle the rejected-promise use case, 
notifying about any promises that, "at the end of the task queue", contain 
rejections that are not yet handled; and 2. A new hook, 
`window.onrejectionhandled`, be added, to notify when (or if) such rejections 
eventually become handled.

By "at the end of the task queue" I mean that upon a promise being rejected 
with no handlers, we would queue a task to fire an error event; however if a 
handler is then attached to a promise in the meantime, a flag would be set so 
that when the task executes nothing actually happens.

### Developer Experience

In terms of developer experience, the result is that if a promise is rejected 
without any rejection handler present, and one is not attached by "the end of 
the event loop turn", the resulting `(message, url, line, column, error, 
promise)` tuple will hit `window.onerror`. If the developer subsequently 
attaches a rejection handler to that promise, then the `promise` object will be 
passed to any handlers for the `rejectionhandled` event.

As usual, if 

Re: [whatwg] An API for unhandled promise rejections

2014-09-12 Thread Boris Zbarsky

On 9/12/14, 4:07 PM, Domenic Denicola wrote:

To state what happens in that scenario more clearly:

- `error` is fired at time zero. Nobody is listening.
- `rejectionhandled` is fired at time 200 ms. Somebody is listening, and "got 
here" is logged.


OK, good.  We're on the same page!

-Boris


Re: [whatwg] An API for unhandled promise rejections

2014-09-12 Thread Domenic Denicola
From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Boris Zbarsky

>> In this case the event would be fired
>
> By "the" event do you mean the error event or the rejectionhandled event?

Ah, trick question! Because, see, I was confused when I wrote that, and myself 
did not know!

>> but no listener would be present at that time, so "got here" would not be 
>> logged.
>
> In my mental model based on your initial mail here, the rejectionhandled 
> event would get fired at the point when catch() is called, which is after 
> window.onrejectionhandled is set.

You are totally right.

To state what happens in that scenario more clearly:

- `error` is fired at time zero. Nobody is listening.
- `rejectionhandled` is fired at time 200 ms. Somebody is listening, and "got 
here" is logged.

So to answer the original question:

> If there is no listener for either when the promise would normally fire 
> error, but then a listener for "rejectionhandled" gets added before a 
> .catch() call on the promise, does the listener get called?

Yes, yes it does. Sorry about the massive confusion. I should probably stop 
writing emails for the night :).


Re: [whatwg] An API for unhandled promise rejections

2014-09-12 Thread Boris Zbarsky

On 9/12/14, 3:45 PM, Domenic Denicola wrote:

var p = Promise.reject(new Error("boo"));

setTimeout(() => {
   window.onrejectionhandled = () => console.log("got here");
}, 100);

setTimeout(() => {
   p.catch(() => {});
}, 200);


That's a good proxy for what I was envisioning...


In this case the event would be fired


By "the" event do you mean the error event or the rejectionhandled event?


but no listener would be present at that time, so "got here" would not be 
logged.


In my mental model based on your initial mail here, the rejectionhandled 
event would get fired at the point when catch() is called, which is 
after window.onrejectionhandled is set.



The promise itself can't be shipped out of the worker scope to the onerror on 
the Worker itself; that's why I was asking what we want to do with workers.  If 
we want a unique key thing there we need some non-object (or at least 
structured clonable) key.


Oh, hmm, I didn't realize you could listen to worker errors via 
`workerInstance.onerror = ...` in the creating script; I thought you were 
referring to `self.onerror = ...` inside the worker.


We have both.  self.onerror gets first dibs at the error, and if it 
doesn't do anything to prevent the error propagating, then 
workerInstance gets an error event fired at it.



More reason for an integer key, I guess. (Call it promiseId, presumably?) The 
alternative would be not letting you catch such errors via 
`workerInstance.onerror`, but I assume that would just complicate things and 
fit poorly with any telemetry frameworks that try to collect errors from both 
the window and any spawned workers.


Yeah, I have no good insights into what, if anything, telemetry 
frameworks do with error events on workers.


-Boris



Re: [whatwg] An API for unhandled promise rejections

2014-09-12 Thread Domenic Denicola
From: Boris Zbarsky [mailto:bzbar...@mit.edu] 

>On 9/12/14, 3:19 PM, Domenic Denicola wrote:
>>> If there is no listener for either when the promise would normally fire 
>>> error, but then a listener for "rejectionhandled" gets added before a 
>>> .catch() call on the promise, does the listener get called?
>>
>> No.
>
> That's not compatible with "the events always get fired", afaict 
> Are we talking about different situations here somehow?

Probably. Some code would help :). I envision the scenario you're describing as:

```js
var p = Promise.reject(new Error("boo"));

setTimeout(() => {
  window.onrejectionhandled = () => console.log("got here");
}, 100);

setTimeout(() => {
  p.catch(() => {});
}, 200);
```

In this case the event would be fired, but no listener would be present at that 
time, so "got here" would not be logged. What scenario were you envisioning?


> The promise itself can't be shipped out of the worker scope to the onerror on 
> the Worker itself; that's why I was asking what we want to do with workers.  
> If we want a unique key thing there we need some non-object (or at least 
> structured clonable) key.

Oh, hmm, I didn't realize you could listen to worker errors via 
`workerInstance.onerror = ...` in the creating script; I thought you were 
referring to `self.onerror = ...` inside the worker.

More reason for an integer key, I guess. (Call it promiseId, presumably?) The 
alternative would be not letting you catch such errors via 
`workerInstance.onerror`, but I assume that would just complicate things and 
fit poorly with any telemetry frameworks that try to collect errors from both 
the window and any spawned workers.



Re: [whatwg] An API for unhandled promise rejections

2014-09-12 Thread Boris Zbarsky

On 9/12/14, 3:19 PM, Domenic Denicola wrote:

If there is no listener for either when the promise would normally fire error, but then a 
listener for "rejectionhandled" gets added before a .catch() call on the 
promise, does the listener get called?


No.


That's not compatible with "the events always get fired", afaict 
Are we talking about different situations here somehow?



This presumably implies keeping the promise alive and not allowing the garbage 
collector to collect it until that task executes, right?


Interesting. This seems OK since it would only be until the queued task 
executes, which should be very soon.


There's no obvious guarantee of that, especially in workers.


But if this complicates implementations undesirably, we could fall back to 
integer IDs or something. The only important thing IMO is being able to match 
up `error` and `rejectionhandled` occurrences, and to me the promise itself was 
a good key.


The promise itself can't be shipped out of the worker scope to the 
onerror on the Worker itself; that's why I was asking what we want to do 
with workers.  If we want a unique key thing there we need some 
non-object (or at least structured clonable) key.


-Boris


Re: [whatwg] An API for unhandled promise rejections

2014-09-12 Thread Domenic Denicola
From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Boris Zbarsky

>> As usual, if one or both of these events is missing listeners, nothing will 
>> happen.
>
> I'm not sure that's "usual".

I think I misspoke here. The events will still be fired! Anything else would be 
insanity. I just meant that from a developer perspective, nothing important 
would occur.

> Specifically, an observable case that's worth considering:  if there is no 
> listener for "error" but there is a listener for "rejectionhandled", does the 
> latter get called?

Yes.

> If there is no listener for either when the promise would normally fire 
> error, but then a listener for "rejectionhandled" gets added before a 
> .catch() call on the promise, does the listener get called?

No.

> It seems to me like from a spec point of view if this sort of thing is done 
> the events should fire unconditionally instead of depending on whether 
> listeners exist, like other events in the platform.  If there really are no 
> listeners, such that UA shenanigans are not observable, UAs are free to 
> perform those shenanigans, whatever they are.

Definitely agreed.

> Worker globals too, right?

Sounds good to me.

> What is the resulting interaction with onerror on the worker object itself?  
> Would we grow an onrejectionhandled attribute on AbstractWorker as well?

Yeah, that would make sense to me.

> This presumably implies keeping the promise alive and not allowing the 
> garbage collector to collect it until that task executes, right?

Interesting. This seems OK since it would only be until the queued task 
executes, which should be very soon. But if this complicates implementations 
undesirably, we could fall back to integer IDs or something. The only important 
thing IMO is being able to match up `error` and `rejectionhandled` occurrences, 
and to me the promise itself was a good key. (I might be missing some use cases 
where the promise comes in handy, but off the top of my head I can't think of 
one.)



Re: [whatwg] An API for unhandled promise rejections

2014-09-12 Thread Boris Zbarsky

On 9/12/14, 2:34 PM, Domenic Denicola wrote:

Thank you for writing this up.  This is definitely an area that needs 
improvement.



As usual, if one or both of these events is missing listeners, nothing will 
happen.


I'm not sure that's "usual".

Specifically, an observable case that's worth considering:  if there is 
no listener for "error" but there is a listener for "rejectionhandled", 
does the latter get called?  If there is no listener for either when the 
promise would normally fire error, but then a listener for 
"rejectionhandled" gets added before a .catch() call on the promise, 
does the listener get called?


It seems to me like from a spec point of view if this sort of thing is 
done the events should fire unconditionally instead of depending on 
whether listeners exist, like other events in the platform.  If there 
really are no listeners, such that UA shenanigans are not observable, 
UAs are free to perform those shenanigans, whatever they are.



We would add a new event to the global, named `rejectionhandled`, along with a 
`RejectionHandledEvent` class that contains only a `promise` member.


Worker globals too, right?

What is the resulting interaction with onerror on the worker object 
itself?  Would we grow an onrejectionhandled attribute on AbstractWorker 
as well?



* When a promise is rejected, if it has no handlers, we would queue a task to 
potentially-fire-an-error.


This presumably implies keeping the promise alive and not allowing the 
garbage collector to collect it until that task executes, right?


-Boris

P.S.  I'm torn on whether to reuse existing onerror mechanisms for this 
or not...


[whatwg] An API for unhandled promise rejections

2014-09-12 Thread Domenic Denicola
## Problem

A common desire in web programming is to log any uncaught exceptions back to 
the server. The typical method for doing this is

window.onerror = (message, url, line, column, error) => {
  // log `error` back to the server
};

When programming asynchronously with promises, asynchronous exceptions are 
encapsulated as _rejected promises_. They can be caught and handled with 
`promise.catch(err => ...)`, and propagate up through an "asynchronous call 
stack" (i.e. a promise chain) in a similar manner to synchronous errors.

However, for promises, there is no notion of the "top-level" of the promise 
chain at which the rejection is known to be unhandled. Promises are inherently 
temporal, and at any time code that has access to a given promise could handle 
the rejection it encapsulates. Thus, unlike with synchronous code, there is not 
an ever-growing list of unhandled exceptions: instead, there is a growing and 
shrinking list of currently-unhandled rejections.

For developers to be able to debug promises effectively, this live list of 
currently-unhandled rejections certainly needs to be exposed via developer 
tools, similar to how devtools exposes the ever-growing list of unhandled 
exceptions (via console output). However, developer tools are not sufficient to 
satisfy the telemetry use case, i.e. the use case which is currently handled 
via `window.onerror` for synchronous code.

## Proposed Solution

We propose that

1. `window.onerror` be extended to handle the rejected-promise use case, 
notifying about any promises that, "at the end of the task queue", contain 
rejections that are not yet handled; and
2. A new hook, `window.onrejectionhandled`, be added, to notify when (or if) 
such rejections eventually become handled.

By "at the end of the task queue" I mean that upon a promise being rejected 
with no handlers, we would queue a task to fire an error event; however if a 
handler is then attached to a promise in the meantime, a flag would be set so 
that when the task executes nothing actually happens.

### Developer Experience

In terms of developer experience, the result is that if a promise is rejected 
without any rejection handler present, and one is not attached by "the end of 
the event loop turn", the resulting `(message, url, line, column, error, 
promise)` tuple will hit `window.onerror`. If the developer subsequently 
attaches a rejection handler to that promise, then the `promise` object will be 
passed to any handlers for the `rejectionhandled` event.

As usual, if one or both of these events is missing listeners, nothing will 
happen. (In this case, the developer likely does not want to do telemetry on 
errors, but instead will be availing themselves to the devtools.)

A robust error-reporting system would use `rejectionhandled` events to cancel 
out earlier `error` events, never displaying them to the person reading the 
error report.

### Specification Details

We would extend 
[`ErrorEvent`](http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#the-errorevent-interface)
 and `ErrorEventInit` with a `promise` member. Similarly, we would extend the  
[`OnErrorEventHandlerNonNull`](http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#onerroreventhandlernonnull)
 callback type to take as its last argument that same promise. In both cases, 
the promise would be `undefined` for synchronous errors.

We would add a new event to the global, named `rejectionhandled`, along with a 
`RejectionHandledEvent` class that contains only a `promise` member.

We would need to hook into rejecting promises and `then`-ing promises, and 
track unhandled rejections:

* When a promise is rejected, if it has no handlers, we would queue a task to 
potentially-fire-an-error.
* When a promise is `then`'d (either by user code or by the spec's chaining 
mechanisms) but the rejection has not yet been reported, we would set a flag 
saying "don't fire that error after all."
* When the task is executed, if that flag is still unset, we would then fire 
the appropriate `error` event.
* If a promise is `then`-ed in such a way as to handle the rejection, but that 
promise had previously been reported as an unhandled rejection, we would need 
to fire the appropriate `rejectionhandled` event.

I can go into details on how to modify the promises spec to have these hooks, 
if desired, as well as how HTML would exploit them to maintain the appropriate 
list and report it at the end of the task queue. I can also help with the spec 
work here, on both the ES side and the HTML side, if desired.

### Potential Variants

The `error` event and its idiosyncratic handler are not the best possible 
extension points. We may be better off with a separate `unhandledrejection` 
event (or, more accurately and as [popular 
libraries](https://github.com/petkaantonov/bluebird/#error-handling) call it, 
`possiblyunhandledrejection`). We could even unify on a single event class