1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

feat: queueMicrotask() error handling (#15522)

Adds error event dispatching for queueMicrotask(). Consequently unhandled errors are now reported with Deno.core.terminate(), which is immune to the existing quirk with plainly thrown errors (#14158).
This commit is contained in:
Nayeem Rahman 2022-08-21 19:16:42 +01:00 committed by GitHub
parent e96933bc16
commit 97954003cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 91 additions and 4 deletions

View file

@ -2745,6 +2745,17 @@ itest!(report_error_end_of_program {
exit_code: 1,
});
itest!(queue_microtask_error {
args: "run --quiet queue_microtask_error.ts",
output: "queue_microtask_error.ts.out",
exit_code: 1,
});
itest!(queue_microtask_error_handled {
args: "run --quiet queue_microtask_error_handled.ts",
output: "queue_microtask_error_handled.ts.out",
});
itest!(spawn_stdout_inherit {
args: "run --quiet --unstable -A spawn_stdout_inherit.ts",
output: "spawn_stdout_inherit.ts.out",

View file

@ -0,0 +1,5 @@
queueMicrotask(() => {
throw new Error("foo");
});
console.log(1);
Promise.resolve().then(() => console.log(2));

View file

@ -0,0 +1,6 @@
1
error: Uncaught Error: foo
throw new Error("foo");
^
at [WILDCARD]/queue_microtask_error.ts:2:9
at deno:core/[WILDCARD]

View file

@ -0,0 +1,21 @@
addEventListener("error", (event) => {
console.log({
cancelable: event.cancelable,
message: event.message,
filename: event.filename,
lineno: event.lineno,
colno: event.colno,
error: event.error,
});
event.preventDefault();
});
onerror = (event) => {
console.log("onerror() called", event.error);
};
queueMicrotask(() => {
throw new Error("foo");
});
console.log(1);
Promise.resolve().then(() => console.log(2));

View file

@ -0,0 +1,15 @@
1
{
cancelable: true,
message: "Uncaught Error: foo",
filename: "[WILDCARD]/queue_microtask_error_handled.ts",
lineno: 18,
colno: 9,
error: Error: foo
at [WILDCARD]/queue_microtask_error_handled.ts:18:9
at deno:core/[WILDCARD]
}
onerror() called Error: foo
at [WILDCARD]/queue_microtask_error_handled.ts:18:9
at deno:core/[WILDCARD]
2

View file

@ -210,8 +210,35 @@
return aggregate;
}
let reportExceptionCallback = undefined;
// Used to report errors thrown from functions passed to `queueMicrotask()`.
// The callback will be passed the thrown error. For example, you can use this
// to dispatch an error event to the global scope.
// In other words, set the implementation for
// https://html.spec.whatwg.org/multipage/webappapis.html#report-the-exception
function setReportExceptionCallback(cb) {
if (typeof cb != "function") {
throw new TypeError("expected a function");
}
reportExceptionCallback = cb;
}
function queueMicrotask(cb) {
return ops.op_queue_microtask(cb);
if (typeof cb != "function") {
throw new TypeError("expected a function");
}
return ops.op_queue_microtask(() => {
try {
cb();
} catch (error) {
if (reportExceptionCallback) {
reportExceptionCallback(error);
} else {
throw error;
}
}
});
}
// Some "extensions" rely on "BadResource" and "Interrupted" errors in the
@ -252,6 +279,7 @@
opCallTraces,
refOp,
unrefOp,
setReportExceptionCallback,
close: (rid) => ops.op_close(rid),
tryClose: (rid) => ops.op_try_close(rid),
read: opAsync.bind(null, "op_read"),

View file

@ -76,7 +76,7 @@ delete Intl.v8BreakIterator;
const errors = window.__bootstrap.errors.errors;
const webidl = window.__bootstrap.webidl;
const domException = window.__bootstrap.domException;
const { defineEventHandler } = window.__bootstrap.event;
const { defineEventHandler, reportException } = window.__bootstrap.event;
const { deserializeJsMessageData, serializeJsMessageData } =
window.__bootstrap.messagePort;
@ -243,6 +243,7 @@ delete Intl.v8BreakIterator;
core.setMacrotaskCallback(timers.handleTimerMacrotask);
core.setMacrotaskCallback(promiseRejectMacrotaskCallback);
core.setWasmStreamingCallback(fetch.handleWasmStreaming);
core.setReportExceptionCallback(reportException);
ops.op_set_format_exception_callback(formatException);
version.setVersions(
runtimeOptions.denoVersion,

View file

@ -3615,7 +3615,7 @@
"type-long-settimeout.any.worker.html": true
},
"microtask-queuing": {
"queue-microtask-exceptions.any.html": false,
"queue-microtask-exceptions.any.html": true,
"queue-microtask.any.html": true,
"queue-microtask.any.worker.html": true
},
@ -4610,4 +4610,4 @@
"idlharness.https.any.worker.html": true,
"idlharness-shadowrealm.window.html": false
}
}
}