Skip to content

Commit

Permalink
Revert "feat: add "unhandledrejection" event support (denoland#12994) (
Browse files Browse the repository at this point in the history
…denoland#15080)"

This reverts commit 1a7259b.
  • Loading branch information
bartlomieju committed Jul 14, 2022
1 parent 91a33c6 commit dba4268
Show file tree
Hide file tree
Showing 10 changed files with 10 additions and 213 deletions.
11 changes: 0 additions & 11 deletions cli/dts/lib.deno.shared_globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,17 +400,6 @@ declare class ErrorEvent extends Event {
constructor(type: string, eventInitDict?: ErrorEventInit);
}

interface PromiseRejectionEventInit extends EventInit {
promise: Promise<any>;
reason?: any;
}

declare class PromiseRejectionEvent extends Event {
readonly promise: Promise<any>;
readonly reason: any;
constructor(type: string, eventInitDict?: PromiseRejectionEventInit);
}

interface AbstractWorkerEventMap {
"error": ErrorEvent;
}
Expand Down
5 changes: 0 additions & 5 deletions cli/tests/integration/run_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2783,8 +2783,3 @@ itest!(followup_dyn_import_resolved {
args: "run --unstable --allow-read followup_dyn_import_resolves/main.ts",
output: "followup_dyn_import_resolves/main.ts.out",
});

itest!(unhandled_rejection {
args: "run --allow-read unhandled_rejection.js",
output: "unhandled_rejection.js.out",
});
11 changes: 0 additions & 11 deletions cli/tests/testdata/unhandled_rejection.js

This file was deleted.

8 changes: 0 additions & 8 deletions cli/tests/testdata/unhandled_rejection.js.out

This file was deleted.

4 changes: 0 additions & 4 deletions core/01_core.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,10 +268,6 @@
terminate: opSync.bind(null, "op_terminate"),
opNames: opSync.bind(null, "op_op_names"),
eventLoopHasMoreWork: opSync.bind(null, "op_event_loop_has_more_work"),
setPromiseRejectCallback: opSync.bind(
null,
"op_set_promise_reject_callback",
),
});

ObjectAssign(globalThis.__bootstrap, { core });
Expand Down
10 changes: 9 additions & 1 deletion core/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,14 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
let state_rc = JsRuntime::state(scope);
let mut state = state_rc.borrow_mut();

// Node compat: perform synchronous process.emit("unhandledRejection").
//
// Note the callback follows the (type, promise, reason) signature of Node's
// internal promiseRejectHandler from lib/internal/process/promises.js, not
// the (promise, reason) signature of the "unhandledRejection" event listener.
//
// Short-circuits Deno's regular unhandled rejection logic because that's
// a) asynchronous, and b) always terminates.
if let Some(js_promise_reject_cb) = state.js_promise_reject_cb.clone() {
let js_uncaught_exception_cb = state.js_uncaught_exception_cb.clone();

Expand Down Expand Up @@ -323,7 +331,6 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
}

if tc_scope.has_caught() {
// TODO(bartlomieju): ensure that TODO provided below is still valid.
// If we get here, an exception was thrown by the unhandledRejection
// handler and there is ether no uncaughtException handler or the
// handler threw an exception of its own.
Expand All @@ -341,6 +348,7 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
} else {
let promise = message.get_promise();
let promise_global = v8::Global::new(scope, promise);

match message.get_event() {
PromiseRejectWithNoHandler => {
let error = message.get_value().unwrap();
Expand Down
48 changes: 0 additions & 48 deletions core/ops_builtin_v8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ pub(crate) fn init_builtins_v8() -> Vec<OpDecl> {
op_apply_source_map::decl(),
op_set_format_exception_callback::decl(),
op_event_loop_has_more_work::decl(),
op_store_pending_promise_exception::decl(),
op_remove_pending_promise_exception::decl(),
op_has_pending_promise_exception::decl(),
]
}

Expand Down Expand Up @@ -795,48 +792,3 @@ fn op_set_format_exception_callback<'a>(
fn op_event_loop_has_more_work(scope: &mut v8::HandleScope) -> bool {
JsRuntime::event_loop_pending_state(scope).is_pending()
}

#[op(v8)]
fn op_store_pending_promise_exception<'a>(
scope: &mut v8::HandleScope<'a>,
promise: serde_v8::Value<'a>,
reason: serde_v8::Value<'a>,
) {
let state_rc = JsRuntime::state(scope);
let mut state = state_rc.borrow_mut();
let promise_value =
v8::Local::<v8::Promise>::try_from(promise.v8_value).unwrap();
let promise_global = v8::Global::new(scope, promise_value);
let error_global = v8::Global::new(scope, reason.v8_value);
state
.pending_promise_exceptions
.insert(promise_global, error_global);
}

#[op(v8)]
fn op_remove_pending_promise_exception<'a>(
scope: &mut v8::HandleScope<'a>,
promise: serde_v8::Value<'a>,
) {
let state_rc = JsRuntime::state(scope);
let mut state = state_rc.borrow_mut();
let promise_value =
v8::Local::<v8::Promise>::try_from(promise.v8_value).unwrap();
let promise_global = v8::Global::new(scope, promise_value);
state.pending_promise_exceptions.remove(&promise_global);
}

#[op(v8)]
fn op_has_pending_promise_exception<'a>(
scope: &mut v8::HandleScope<'a>,
promise: serde_v8::Value<'a>,
) -> bool {
let state_rc = JsRuntime::state(scope);
let state = state_rc.borrow();
let promise_value =
v8::Local::<v8::Promise>::try_from(promise.v8_value).unwrap();
let promise_global = v8::Global::new(scope, promise_value);
state
.pending_promise_exceptions
.contains_key(&promise_global)
}
53 changes: 0 additions & 53 deletions ext/web/02_event.js
Original file line number Diff line number Diff line change
Expand Up @@ -1278,58 +1278,6 @@
[SymbolToStringTag] = "ProgressEvent";
}

class PromiseRejectionEvent extends Event {
#promise = null;
#reason = null;

get promise() {
return this.#promise;
}
get reason() {
return this.#reason;
}

constructor(
type,
{
bubbles,
cancelable,
composed,
promise,
reason,
} = {},
) {
super(type, {
bubbles: bubbles,
cancelable: cancelable,
composed: composed,
});

this.#promise = promise;
this.#reason = reason;
}

[SymbolFor("Deno.privateCustomInspect")](inspect) {
return inspect(consoleInternal.createFilteredInspectProxy({
object: this,
evaluate: this instanceof PromiseRejectionEvent,
keys: [
...EVENT_PROPS,
"promise",
"reason",
],
}));
}

// TODO(lucacasonato): remove when this interface is spec aligned
[SymbolToStringTag] = "PromiseRejectionEvent";
}

defineEnumerableProps(PromiseRejectionEvent, [
"promise",
"reason",
]);

const _eventHandlers = Symbol("eventHandlers");

function makeWrappedHandler(handler, isSpecialErrorEventHandler) {
Expand Down Expand Up @@ -1478,7 +1426,6 @@
window.MessageEvent = MessageEvent;
window.CustomEvent = CustomEvent;
window.ProgressEvent = ProgressEvent;
window.PromiseRejectionEvent = PromiseRejectionEvent;
window.dispatchEvent = EventTarget.prototype.dispatchEvent;
window.addEventListener = EventTarget.prototype.addEventListener;
window.removeEventListener = EventTarget.prototype.removeEventListener;
Expand Down
72 changes: 0 additions & 72 deletions runtime/js/99_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ delete Intl.v8BreakIterator;
((window) => {
const core = Deno.core;
const {
ArrayPrototypeIndexOf,
ArrayPrototypePush,
ArrayPrototypeShift,
ArrayPrototypeSplice,
ArrayPrototypeMap,
DateNow,
Error,
Expand All @@ -31,11 +27,7 @@ delete Intl.v8BreakIterator;
SymbolFor,
SymbolIterator,
PromisePrototypeThen,
SafeWeakMap,
TypeError,
WeakMapPrototypeDelete,
WeakMapPrototypeGet,
WeakMapPrototypeSet,
} = window.__bootstrap.primordials;
const util = window.__bootstrap.util;
const eventTarget = window.__bootstrap.eventTarget;
Expand Down Expand Up @@ -241,7 +233,6 @@ delete Intl.v8BreakIterator;

function runtimeStart(runtimeOptions, source) {
core.setMacrotaskCallback(timers.handleTimerMacrotask);
core.setMacrotaskCallback(promiseRejectMacrotaskCallback);
core.setWasmStreamingCallback(fetch.handleWasmStreaming);
core.opSync("op_set_format_exception_callback", formatException);
version.setVersions(
Expand Down Expand Up @@ -420,7 +411,6 @@ delete Intl.v8BreakIterator;
PerformanceEntry: util.nonEnumerable(performance.PerformanceEntry),
PerformanceMark: util.nonEnumerable(performance.PerformanceMark),
PerformanceMeasure: util.nonEnumerable(performance.PerformanceMeasure),
PromiseRejectionEvent: util.nonEnumerable(PromiseRejectionEvent),
ProgressEvent: util.nonEnumerable(ProgressEvent),
ReadableStream: util.nonEnumerable(streams.ReadableStream),
ReadableStreamDefaultReader: util.nonEnumerable(
Expand Down Expand Up @@ -563,60 +553,6 @@ delete Intl.v8BreakIterator;
postMessage: util.writable(postMessage),
};

const pendingRejections = [];
const pendingRejectionsReasons = new SafeWeakMap();

function promiseRejectCallback(type, promise, reason) {
switch (type) {
case 0: {
core.opSync("op_store_pending_promise_exception", promise, reason);
ArrayPrototypePush(pendingRejections, promise);
WeakMapPrototypeSet(pendingRejectionsReasons, promise, reason);
break;
}
case 1: {
core.opSync("op_remove_pending_promise_exception", promise);
const index = ArrayPrototypeIndexOf(pendingRejections, promise);
if (index > -1) {
ArrayPrototypeSplice(pendingRejections, index, 1);
WeakMapPrototypeDelete(pendingRejectionsReasons, promise);
}
break;
}
default:
return;
}
}

function promiseRejectMacrotaskCallback() {
while (pendingRejections.length > 0) {
const promise = ArrayPrototypeShift(pendingRejections);
const hasPendingException = core.opSync(
"op_has_pending_promise_exception",
promise,
);
const reason = WeakMapPrototypeGet(pendingRejectionsReasons, promise);
WeakMapPrototypeDelete(pendingRejectionsReasons, promise);

if (!hasPendingException) {
return;
}

const event = new PromiseRejectionEvent("unhandledrejection", {
cancelable: true,
promise,
reason,
});
globalThis.dispatchEvent(event);

// If event was not prevented we will let Rust side handle it.
if (event.defaultPrevented) {
core.opSync("op_remove_pending_promise_exception", promise);
}
}
return true;
}

let hasBootstrapped = false;

function bootstrapMainRuntime(runtimeOptions) {
Expand Down Expand Up @@ -649,10 +585,6 @@ delete Intl.v8BreakIterator;
defineEventHandler(window, "load");
defineEventHandler(window, "beforeunload");
defineEventHandler(window, "unload");
defineEventHandler(window, "unhandledrejection");

core.setPromiseRejectCallback(promiseRejectCallback);

const isUnloadDispatched = SymbolFor("isUnloadDispatched");
// Stores the flag for checking whether unload is dispatched or not.
// This prevents the recursive dispatches of unload events.
Expand Down Expand Up @@ -753,10 +685,6 @@ delete Intl.v8BreakIterator;

defineEventHandler(self, "message");
defineEventHandler(self, "error", undefined, true);
defineEventHandler(self, "unhandledrejection");

core.setPromiseRejectCallback(promiseRejectCallback);

// `Deno.exit()` is an alias to `self.close()`. Setting and exit
// code using an op in worker context is a no-op.
os.setExitHandler((_exitCode) => {
Expand Down
1 change: 1 addition & 0 deletions tools/wpt/expectation.json
Original file line number Diff line number Diff line change
Expand Up @@ -4360,6 +4360,7 @@
"The CanvasPath interface object should be exposed.",
"The TextMetrics interface object should be exposed.",
"The Path2D interface object should be exposed.",
"The PromiseRejectionEvent interface object should be exposed.",
"The EventSource interface object should be exposed.",
"The XMLHttpRequestEventTarget interface object should be exposed.",
"The XMLHttpRequestUpload interface object should be exposed.",
Expand Down

0 comments on commit dba4268

Please sign in to comment.