This repository is a place to work on some spec patches to HTML and ECMAScript to add support for events to track unhandled promise rejections, as originally proposed on the WHATWG mailing list.
Add the following row to the table of internal slots:
Internal Slot | Description |
---|---|
[[PromiseIsHandled]] | A boolean indicating whether the promise has ever had a fulfillment or rejection handler, used in unhandled rejection tracking |
Add an additional step between steps 6 and 7:
- Set promise's [[PromiseIsHandled]] internal slot to false.
Add an additional step between steps 6 and 7:
- If the value of promise's [[PromiseIsHandled]] internal slot is false, perform HostPromiseRejectionTracker(promise,
"reject"
).
Add an additional step nested inside step 9, between 9a and 9b:
- If the value of promise's [[PromiseIsHandled]] internal slot is false, perform HostPromiseRejectionTracker(promise,
"handle"
).
Add an additional step between steps 9 and 10:
- Set promise's [[PromiseIsHandled]] internal slot to true.
Add an additional section as follows:
HostPromiseRejectionTracker is an implementation-defined abstract operation that allows host environments to track promise rejections.
The default implementation of HostPromiseRejectionTracker is to do nothing. An implementation of HostPromiseRejectionTracker must complete normally in all cases.
NOTE 1 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.
NOTE 2 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.
Environment settings object seems to be a place to dump stuff? Need to define these.
- Outstanding rejected promises weak set
- About-to-be-notified rejected promises list
Implementations are free to limit the size of the rejected promises weak set, e.g. removing old entries from it when new ones are added.
Insert a step between steps 8 and 9:
- Done: If the about-to-be-notified rejected promises list is not empty,
- Queue a task to notify about the rejected promises currently in the about-to-be-notified rejected promises list.
- Clear the about-to-be-notified rejected promises list.
Modify step 9 to remove the "Done:" label from it.
(This section probably belongs somewhere within the Scripting section, probably right after Runtime script errors.)
In addition to synchronous runtime script errors, scripts may experience asynchronous promise rejections, tracked via the unhandledrejection
and rejectionhandled
events.
ECMAScript contains an implementation-defined HostPromiseRejectionTracker(promise, operation) abstract operation. User agents must use the following implementation.
- If operation is
"reject"
,- Add promise to the about-to-be-notified rejected promises list.
- If operation is
"handle"
,- If the about-to-be-notified rejected promises list contains promise, remove promise from the about-to-be-notified rejected promises list and return.
- If the outstanding rejected promises weak set does not contain promise then return.
- Remove promise from the outstanding rejected promises weak set.
- Queue a task to perform the following steps:
- Let event be a new trusted
PromiseRejectionEvent
object that does not bubble and is not cancelable, and which has the event namerejectionhandled
. - Initialise event's
promise
attribute to promise. - Initialise event's
reason
attribute to the value of promise's [[PromiseResult]] internal slot. - Dispatch event at the current script's global object.
- Let event be a new trusted
To notify about a list of rejected promises, given a list list, perform the following steps:
- For each entry p in list,
- If p's [[PromiseIsHandled]] internal slot is true, continue to the next iteration of the loop.
- Let event be a new trusted
PromiseRejectionEvent
object that does not bubble and is cancelable, and which has the event nameunhandledrejection
. - Initialise event's
promise
attribute to p. - Initialise event's
reason
attribute to the value of p's [[PromiseResult]] internal slot. - Dispatch event at the current script's global object.
- If event was canceled, then the promise rejection is handled. Otherwise, the promise rejection is not handled.
- If p's [[PromiseIsHandled]] internal slot is false, add p to the outstanding rejected promises weak set.
This implementation results in promise rejections being marked as handled or not handled. These concepts parallel handled and not handled for script errors.
NOTE: Implementations should use the handled/not handled state of promise rejections when determining what to log in any debugging interfaces. That is, intercepting an unhandledrejection
event and calling preventDefault()
should prevent the corresponding rejection from showing up in the developer console or similar.
[Constructor(DOMString type, optional PromiseRejectionEventInit eventInitDict), Exposed=(Window,Worker,ServiceWorker)]
interface PromiseRejectionEvent : Event {
readonly attribute Promise<any>? promise;
readonly attribute any reason;
};
dictionary PromiseRejectionEventInit : EventInit {
required Promise<any>? promise;
any reason = null;
};
The promise
attribute must return the value it was initialised to. It represents the promise which this notification is about.
The reason
attribute must return the value it was initialized to. It represents the rejection reason for the promise.
Add
attribute EventHandler onunhandledrejection;
attribute EventHandler onrejectionhandled;
Add
attribute EventHandler onunhandledrejection;
attribute EventHandler onrejectionhandled;