From e89e31d60feaed57f0450a929ef6a0a6138f1204 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Fri, 2 Oct 2015 15:32:58 -0400 Subject: [PATCH] Layering: Add HostPromiseRejectionTracker This is a non-observable change that will allow HTML to provide events for tracking promise rejections, as outlined in https://github.com/domenic/unhandled-rejections-browser-spec. For more information on the original proposal and use cases (mostly on the HTML side), see https://lists.w3.org/Archives/Public/public-whatwg-archive/2014Sep/0024.html. The corresponding HTML pull request is at https://github.com/whatwg/html/pull/224. --- spec.html | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index 8b2631b8b1..e914bbda01 100644 --- a/spec.html +++ b/spec.html @@ -34518,7 +34518,7 @@

IsPromise ( _x_ )

-

RejectPromise ( _promise_, _reason_)

+

RejectPromise ( _promise_, _reason_ )

When the RejectPromise abstract operation is called with arguments _promise_ and _reason_ the following steps are taken:

1. Assert: the value of _promise_'s [[PromiseState]] internal slot is `"pending"`. @@ -34527,6 +34527,7 @@

RejectPromise ( _promise_, _reason_)

1. Set the value of _promise_'s [[PromiseFulfillReactions]] internal slot to *undefined*. 1. Set the value of _promise_'s [[PromiseRejectReactions]] internal slot to *undefined*. 1. Set the value of _promise_'s [[PromiseState]] internal slot to `"rejected"`. + 1. If the value of _promise_'s [[PromiseIsHandled]] internal slot is *false*, perform HostPromiseRejectionTracker(_promise_, `"reject"`). 1. Return TriggerPromiseReactions(_reactions_, _reason_).
@@ -34541,6 +34542,29 @@

TriggerPromiseReactions ( _reactions_, _argument_ )

1. Return *undefined*. + + +

HostPromiseRejectionTracker ( promise, operation )

+ +

HostPromiseRejectionTracker is an implementation-defined abstract operation that allows host environments to track promise rejections.

+ +

An implementation of HostPromiseRejectionTracker must complete normally in all cases. The default implementation of HostPromiseRejectionTracker is to do nothing.

+ + +

HostPromiseRejectionTracker is called in two scenarios:

+ +
    +
  • When a promise is rejected without any handlers, it is called with its _operation_ argument set to `"reject"`.
  • +
  • When a handler is added to a rejected promise for the first time, it is called with its _operation_ argument set to `"handle"`.
  • +
+ +

A typical implementation of HostPromiseRejectionTracker might try to notify developers of unhandled rejections, while also being careful to notify them if such previous notifications are later invalidated by new handlers being attached.

+
+ + +

If _operation_ is `"handle"`, an implementation should not hold a reference to promise in a way that would interfere with garbage collection. An implementation may hold a reference to promise if operation is `"reject"`, since it is expected that rejections will be rare and not on hot code paths.

+
+
@@ -34597,10 +34621,11 @@

Promise ( _executor_ )

1. If NewTarget is *undefined*, throw a *TypeError* exception. 1. If IsCallable(_executor_) is *false*, throw a *TypeError* exception. - 1. Let _promise_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%PromisePrototype%"`, «[[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]]» ). + 1. Let _promise_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%PromisePrototype%"`, «[[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]], [[PromiseIsHandled]]» ). 1. Set _promise_'s [[PromiseState]] internal slot to `"pending"`. 1. Set _promise_'s [[PromiseFulfillReactions]] internal slot to a new empty List. 1. Set _promise_'s [[PromiseRejectReactions]] internal slot to a new empty List. + 1. Set _promise_'s [[PromiseIsHandled]] internal slot to *false*. 1. Let _resolvingFunctions_ be CreateResolvingFunctions(_promise_). 1. Let _completion_ be Call(_executor_, *undefined*, «_resolvingFunctions_.[[Resolve]], _resolvingFunctions_.[[Reject]]»). 1. If _completion_ is an abrupt completion, then @@ -34861,7 +34886,9 @@

PerformPromiseThen ( _promise_, _onFulfilled_, _onRejected_, _resultCapabili 1. Else, 1. Assert: The value of _promise_'s [[PromiseState]] internal slot is `"rejected"`. 1. Let _reason_ be the value of _promise_'s [[PromiseResult]] internal slot. + 1. If the value of _promise_'s [[PromiseIsHandled]] internal slot is *false*, perform HostPromiseRejectionTracker(_promise_, `"handle"`). 1. Perform EnqueueJob(`"PromiseJobs"`, PromiseReactionJob, «_rejectReaction_, _reason_»). + 1. Set _promise_'s [[PromiseIsHandled]] internal slot to *true*. 1. Return _resultCapability_.[[Promise]]. @@ -34922,6 +34949,14 @@

Properties of Promise Instances

A List of PromiseReaction records to be processed when/if the promise transitions from the `"pending"` state to the `"rejected"` state. + + + [[PromiseIsHandled]] + + + A boolean indicating whether the promise has ever had a fulfillment or rejection handler; used in unhandled rejection tracking. + +