Skip to content

jeisinger/unhandled-rejections-browser-spec

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 

Repository files navigation

Unhandled Rejection Tracking Browser Events

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.

Changes to ECMAScript

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:

  1. Set promise's [[PromiseIsHandled]] internal slot to false.

Add an additional step between steps 6 and 7:

  1. 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:

  1. If the value of promise's [[PromiseIsHandled]] internal slot is false, perform HostPromiseRejectionTracker(promise, "handle").

Add an additional step between steps 9 and 10:

  1. Set promise's [[PromiseIsHandled]] internal slot to true.

Add an additional section as follows:

HostPromiseRejectionTracker( promise, operation )

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.

Changes to HTML

Stuff to put somewhere

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:

  1. Done: If the about-to-be-notified rejected promises list is not empty,
  2. Queue a task to notify about the rejected promises currently in the about-to-be-notified rejected promises list.
  3. Clear the about-to-be-notified rejected promises list.

Modify step 9 to remove the "Done:" label from it.

Unhandled promise rejections

(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.

The HostPromiseRejectionTracker implementation

ECMAScript contains an implementation-defined HostPromiseRejectionTracker(promise, operation) abstract operation. User agents must use the following implementation.

  1. If operation is "reject",
    1. Add promise to the about-to-be-notified rejected promises list.
  2. If operation is "handle",
    1. If the about-to-be-notified rejected promises list contains promise, remove promise from the about-to-be-notified rejected promises list and return.
    2. If the outstanding rejected promises weak set does not contain promise then return.
    3. Remove promise from the outstanding rejected promises weak set.
    4. Queue a task to perform the following steps:
      1. Let event be a new trusted PromiseRejectionEvent object that does not bubble and is not cancelable, and which has the event name rejectionhandled.
      2. Initialise event's promise attribute to promise.
      3. Initialise event's reason attribute to the value of promise's [[PromiseResult]] internal slot.
      4. Dispatch event at the current script's global object.

Notification of rejected promises

To notify about a list of rejected promises, given a list list, perform the following steps:

  1. For each entry p in list,
    1. If p's [[PromiseIsHandled]] internal slot is true, continue to the next iteration of the loop.
    2. Let event be a new trusted PromiseRejectionEvent object that does not bubble and is cancelable, and which has the event name unhandledrejection.
    3. Initialise event's promise attribute to p.
    4. Initialise event's reason attribute to the value of p's [[PromiseResult]] internal slot.
    5. Dispatch event at the current script's global object.
    6. If event was canceled, then the promise rejection is handled. Otherwise, the promise rejection is not handled.
    7. 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.

The PromiseRejectionEvent interface

[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;

About

Spec patches for HTML and ES for tracking unhandled promise rejections with events

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 79.5%
  • HTML 20.5%