chore: bump deno_core and update tests (#21467)

Landing changes required for
https://github.com/denoland/deno_core/pull/359

We needed to update 99_main.js and a whole load of tests.

API changes:

- setPromiseRejectCallback becomes setUnhandledPromiseRejectionHandler.
The function is now called from eventLoopTick.
- The promiseRejectMacrotaskCallback no longer exists, as this is
automatically handled in eventLoopTick.
- ops.op_dispatch_exception now takes a second parameter: in_promise.
The preferred way to call this op is now reportUnhandledException or
reportUnhandledPromiseRejection.
This commit is contained in:
Matt Mastracci 2023-12-06 17:02:52 -07:00 committed by GitHub
parent 68d356eed9
commit 9314928990
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 106 additions and 192 deletions

12
Cargo.lock generated
View file

@ -1065,9 +1065,9 @@ dependencies = [
[[package]]
name = "deno_core"
version = "0.234.0"
version = "0.235.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94fe0979c3e6fe8fada5d4895ddd043fb8d5936e0f4c4b4e76fab403bf21ee22"
checksum = "dd09a1db8195a505dcb50664a3d932f75be9acaeb84b8952da3cf0a0b8309916"
dependencies = [
"anyhow",
"bytes",
@ -1493,9 +1493,9 @@ dependencies = [
[[package]]
name = "deno_ops"
version = "0.110.0"
version = "0.111.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dab9fca550a1241267e56a9a8185f6263964233f980233cf70d47e587b5f866f"
checksum = "4bdb7fe6c12234bf3b7542ff6d16951f9573c946280d918e21c7a7262907b9a7"
dependencies = [
"proc-macro-rules",
"proc-macro2",
@ -4638,9 +4638,9 @@ dependencies = [
[[package]]
name = "serde_v8"
version = "0.143.0"
version = "0.144.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "331359280930e186b14c0f931433b75ec174edb017fa390bab8716d8e36c29ee"
checksum = "73f73d99493115f9f3a9377c8e167e542da223da7a6d13f51b78912eb12d48ef"
dependencies = [
"bytes",
"derive_more",

View file

@ -40,7 +40,7 @@ repository = "https://github.com/denoland/deno"
[workspace.dependencies]
deno_ast = { version = "0.31.6", features = ["transpiling"] }
deno_core = { version = "0.234.0" }
deno_core = { version = "0.235.0" }
deno_runtime = { version = "0.135.0", path = "./runtime" }
napi_sym = { version = "0.57.0", path = "./cli/napi/sym" }

View file

@ -105,7 +105,7 @@ fn standalone_error() {
let stderr = output.stderr();
// On Windows, we cannot assert the file path (because '\').
// Instead we just check for relevant output.
assert_contains!(stderr, "error: Uncaught Error: boom!");
assert_contains!(stderr, "error: Uncaught (in promise) Error: boom!");
assert_contains!(stderr, "throw new Error(\"boom!\");");
assert_contains!(stderr, "\n at boom (file://");
assert_contains!(stderr, "standalone_error.ts:2:9");
@ -145,7 +145,7 @@ fn standalone_error_module_with_imports() {
let stderr = output.stderr();
// On Windows, we cannot assert the file path (because '\').
// Instead we just check for relevant output.
assert_contains!(stderr, "error: Uncaught Error: boom!");
assert_contains!(stderr, "error: Uncaught (in promise) Error: boom!");
assert_contains!(stderr, "throw new Error(\"boom!\");");
assert_contains!(stderr, "\n at file://");
assert_contains!(stderr, "standalone_error_module_with_imports_2.ts:2:7");

View file

@ -825,7 +825,7 @@ fn repl_reject() {
console.write_line(r#"Promise.reject(new Error("foo"));"#);
console.expect("Promise {");
console.expect(" <rejected> Error: foo");
console.expect("Uncaught (in promise) Error: foo");
console.expect("Uncaught Error: foo");
console.expect(" at <anonymous>");
console.write_line("console.log(2);");
console.expect("2");
@ -857,7 +857,7 @@ fn repl_error_undefined() {
console.expect("Uncaught undefined");
console.write_line(r#"Promise.reject();"#);
console.expect("Promise { <rejected> undefined }");
console.expect("Uncaught (in promise) undefined");
console.expect("Uncaught undefined");
console.write_line(r#"reportError(undefined);"#);
console.expect("undefined");
console.expect("Uncaught undefined");

View file

@ -3926,7 +3926,7 @@ async fn test_resolve_dns() {
let out = String::from_utf8_lossy(&output.stdout);
assert!(!output.status.success());
assert!(err.starts_with("Check file"));
assert!(err.contains(r#"error: Uncaught PermissionDenied: Requires net access to "127.0.0.1:4553""#));
assert!(err.contains(r#"error: Uncaught (in promise) PermissionDenied: Requires net access to "127.0.0.1:4553""#));
assert!(out.is_empty());
}
@ -3947,7 +3947,7 @@ async fn test_resolve_dns() {
let out = String::from_utf8_lossy(&output.stdout);
assert!(!output.status.success());
assert!(err.starts_with("Check file"));
assert!(err.contains(r#"error: Uncaught PermissionDenied: Requires net access to "127.0.0.1:4553""#));
assert!(err.contains(r#"error: Uncaught (in promise) PermissionDenied: Requires net access to "127.0.0.1:4553""#));
assert!(out.is_empty());
}
@ -4067,7 +4067,7 @@ fn broken_stdout() {
assert!(!output.status.success());
let stderr = std::str::from_utf8(output.stderr.as_ref()).unwrap().trim();
assert!(stderr.contains("Uncaught BrokenPipe"));
assert!(stderr.contains("Uncaught (in promise) BrokenPipe"));
assert!(!stderr.contains("panic"));
}

View file

@ -967,7 +967,11 @@ async fn run_watch_error_messages() {
let (_, mut stderr_lines) = child_lines(&mut child);
wait_contains("Process started", &mut stderr_lines).await;
wait_contains("error: Uncaught SyntaxError: outer", &mut stderr_lines).await;
wait_contains(
"error: Uncaught (in promise) SyntaxError: outer",
&mut stderr_lines,
)
.await;
wait_contains("Caused by: TypeError: inner", &mut stderr_lines).await;
wait_contains("Process failed", &mut stderr_lines).await;

View file

@ -1,4 +1,4 @@
error: TypeError: Cannot read properties of undefined (reading 'fn')
error: (in promise) TypeError: Cannot read properties of undefined (reading 'fn')
Deno.bench();
^
at [WILDCARD]

View file

@ -1,4 +1,4 @@
error: Uncaught AggregateError
error: Uncaught (in promise) AggregateError
Error: bar <ref *1>
at file:///[WILDCARD]/error_cause_recursive_aggregate.ts:2:13
Caused by: Error: foo

View file

@ -1,4 +1,4 @@
error: Uncaught Error: baz
error: Uncaught (in promise) Error: baz
const baz = new Error("baz", { cause: bar });
^
at file:///[WILDCARD]/error_cause_recursive_tail.ts:3:13

View file

@ -1,3 +1,3 @@
error: Uncaught Error: require() of ES Module [WILDCARD]esm.js from [WILDCARD]main.ts not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.
error: Uncaught (in promise) Error: require() of ES Module [WILDCARD]esm.js from [WILDCARD]main.ts not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.
at [WILDCARD]
at file:///[WILDCARD]/require_esm_error/main.ts:5:1

View file

@ -1,2 +1,2 @@
error: Uncaught Error: require() of ES Module [WILDCARD]my_esm_module.js from [WILDCARD]index.js not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.
error: Uncaught (in promise) Error: require() of ES Module [WILDCARD]my_esm_module.js from [WILDCARD]index.js not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.
[WILDCARD]

View file

@ -1,2 +1,2 @@
error: Uncaught Error: require() of ES Module [WILDCARD]esm_mjs.mjs from [WILDCARD]require_mjs.js not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.
error: Uncaught (in promise) Error: require() of ES Module [WILDCARD]esm_mjs.mjs from [WILDCARD]require_mjs.js not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.
[WILDCARD]

View file

@ -1,5 +1,5 @@
1
1
error: Uncaught TypeError: this.otherMethod is not a function
error: Uncaught (in promise) TypeError: this.otherMethod is not a function
at getValue (file://[WILDCARD]/@denotest/cjs-this-in-exports/1.0.0/index.js:3:17)
at file://[WILDCARD]/testdata/npm/cjs_this_in_exports/main.js:11:1

View file

@ -1,4 +1,4 @@
[WILDCARD]error: Uncaught PermissionDenied: Requires read access to "non-existent", run again with the --allow-read flag
[WILDCARD]error: Uncaught (in promise) PermissionDenied: Requires read access to "non-existent", run again with the --allow-read flag
Deno.readFileSync("non-existent");
^
at [WILDCARD]

View file

@ -1,2 +1,2 @@
[WILDCARD]error: Uncaught TypeError: Invalid URL: ''
[WILDCARD]error: Uncaught (in promise) TypeError: Invalid URL: ''
[WILDCARD]

View file

@ -1,2 +1,2 @@
[WILDCARD]error: Uncaught Error: foo
[WILDCARD]error: Uncaught (in promise) Error: foo
[WILDCARD]

View file

@ -8,7 +8,7 @@ AggregateError: Multiple errors.
at [WILDCARD]/aggregate_error.ts:3:3
at [WILDCARD]/aggregate_error.ts:1:24
error: Uncaught AggregateError: Multiple errors.
error: Uncaught (in promise) AggregateError: Multiple errors.
Error: Error message 1.
at [WILDCARD]/aggregate_error.ts:2:3
Error: Error message 2.

View file

@ -16,7 +16,7 @@ AggregateError: foo1
Caused by AggregateError: foo2
at [WILDCARD]/complex_error.ts:8:12
error: Uncaught AggregateError: foo1
error: Uncaught (in promise) AggregateError: foo1
AggregateError
Error: qux1
at [WILDCARD]/complex_error.ts:3:25

View file

@ -1,3 +1,3 @@
[WILDCARD]error: Uncaught SyntaxError: foo
[WILDCARD]error: Uncaught (in promise) SyntaxError: foo
[WILDCARD]
at file:///[WILDCARD]/dom_exception_formatting.ts:[WILDCARD]

View file

@ -1,4 +1,4 @@
[WILDCARD]error: Uncaught Error: bad
[WILDCARD]error: Uncaught (in promise) Error: bad
throw Error("bad");
^
at foo ([WILDCARD]/error_001.ts:2:9)

View file

@ -1,4 +1,4 @@
[WILDCARD]error: Uncaught Error: exception from mod1
[WILDCARD]error: Uncaught (in promise) Error: exception from mod1
throw Error("exception from mod1");
^
at throwsError ([WILDCARD]/subdir/mod1.ts:16:9)

View file

@ -1 +1 @@
[WILDCARD]error: Uncaught { foo: "bar" }
[WILDCARD]error: Uncaught (in promise) { foo: "bar" }

View file

@ -1,4 +1,4 @@
[WILDCARD]error: Uncaught ReferenceError: consol is not defined
[WILDCARD]error: Uncaught (in promise) ReferenceError: consol is not defined
consol.log("hello world!");
^
at [WILDCARD]/error_008_checkjs.js:2:1

View file

@ -1,4 +1,4 @@
[WILDCARD]error: Uncaught TypeError: Failed to construct 'Event': 1 argument required, but only 0 present.
[WILDCARD]error: Uncaught (in promise) TypeError: Failed to construct 'Event': 1 argument required, but only 0 present.
new Event();
^
at [WILDCARD]

View file

@ -1,2 +1,2 @@
error: Uncaught TypeError: Cannot read properties of undefined (reading 'a')
error: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'a')
at file:///[WILDCARD]/error_018_hide_long_source_js.js:3:206

View file

@ -1,7 +1,7 @@
[WILDCARD]Error: function
at foo ([WILDCARD]/error_019_stack_function.ts:[WILDCARD])
at [WILDCARD]/error_019_stack_function.ts:[WILDCARD]
error: Uncaught Error: function
error: Uncaught (in promise) Error: function
throw new Error("function");
^
at foo ([WILDCARD]/error_019_stack_function.ts:[WILDCARD])

View file

@ -1,7 +1,7 @@
[WILDCARD]Error: constructor
at new A ([WILDCARD]/error_020_stack_constructor.ts:[WILDCARD])
at [WILDCARD]/error_020_stack_constructor.ts:[WILDCARD]
error: Uncaught Error: constructor
error: Uncaught (in promise) Error: constructor
throw new Error("constructor");
^
at new A ([WILDCARD]/error_020_stack_constructor.ts:[WILDCARD])

View file

@ -1,7 +1,7 @@
[WILDCARD]Error: method
at A.m ([WILDCARD]/error_021_stack_method.ts:[WILDCARD])
at [WILDCARD]/error_021_stack_method.ts:[WILDCARD]
error: Uncaught Error: method
error: Uncaught (in promise) Error: method
throw new Error("method");
^
at A.m ([WILDCARD]/error_021_stack_method.ts:[WILDCARD])

View file

@ -1,6 +1,6 @@
[WILDCARD]CustomError: custom error
at [WILDCARD]/error_022_stack_custom_error.ts:[WILDCARD]
error: Uncaught CustomError: custom error
error: Uncaught (in promise) CustomError: custom error
const error = new CustomError();
^
at [WILDCARD]/error_022_stack_custom_error.ts:[WILDCARD]

View file

@ -2,7 +2,7 @@
at [WILDCARD]/error_023_stack_async.ts:[WILDCARD]
at async [WILDCARD]/error_023_stack_async.ts:[WILDCARD]
at async [WILDCARD]/error_023_stack_async.ts:[WILDCARD]
error: Uncaught Error: async
error: Uncaught (in promise) Error: async
throw new Error("async");
^
at [WILDCARD]/error_023_stack_async.ts:[WILDCARD]

View file

@ -2,7 +2,7 @@
at [WILDCARD]/error_024_stack_promise_all.ts:[WILDCARD]
at async Promise.all (index 1)
at async [WILDCARD]/error_024_stack_promise_all.ts:[WILDCARD]
error: Uncaught Error: Promise.all()
error: Uncaught (in promise) Error: Promise.all()
throw new Error("Promise.all()");
^
at [WILDCARD]/error_024_stack_promise_all.ts:[WILDCARD]

View file

@ -1,4 +1,4 @@
[WILDCARD]error: Uncaught Error: bad
[WILDCARD]error: Uncaught (in promise) Error: bad
throw Error("bad");
^
at foo ([WILDCARD]/error_025_tab_indent:2:8)

View file

@ -1,5 +1,5 @@
[WILDCARD]
error: Uncaught Error: bad
error: Uncaught (in promise) Error: bad
throw Error("bad");
^
at foo (http://localhost:4545/run/error_001.ts:2:9)

View file

@ -1,4 +1,4 @@
error: Uncaught Error: foo
error: Uncaught (in promise) Error: foo
throw new Error("foo", { cause: new Error("bar", { cause: "deno" as any }) });
^
at a (file:///[WILDCARD]/error_cause.ts:3:9)

View file

@ -1,4 +1,4 @@
error: Uncaught Error: bar <ref *1>
error: Uncaught (in promise) Error: bar <ref *1>
const y = new Error("bar", { cause: x });
^
at file:///[WILDCARD]/error_cause_recursive.ts:2:11

View file

@ -1,4 +1,4 @@
error: Uncaught Error
error: Uncaught (in promise) Error
throw new ErrorNameNonString();
^
at file:///[WILDCARD]/error_name_non_string.js:[WILDCARD]

View file

@ -11,7 +11,7 @@ Error: Error with errors prop.
]
}
error: Uncaught Error: Error with errors prop.
error: Uncaught (in promise) Error: Error with errors prop.
const error = new Error("Error with errors prop.");
^
at [WILDCARD]/error_with_errors_prop.js:1:15

View file

@ -1,10 +1,4 @@
error: Uncaught (in promise) TypeError: Unsupported scheme "ext" for module "ext:runtime/01_errors.js". Supported schemes: [
"data",
"blob",
"file",
"http",
"https",
]
error: Uncaught (in promise) TypeError: Importing ext: modules is only allowed from ext: and node: modules. Tried to import ext:runtime/01_errors.js from [WILDCARD]/testdata/run/extension_dynamic_import.ts
await import("ext:runtime/01_errors.js");
^
at async [WILDCARD]/extension_dynamic_import.ts:1:1
at async [WILDCARD]/run/extension_dynamic_import.ts:1:1

View file

@ -1,4 +1,4 @@
error: Uncaught Error: Hello 2
error: Uncaught (in promise) Error: Hello 2
throw new Error(`Hello ${A.C}`);
^
at a (data:application/typescript;base64,ZW51bSBBIHsKICBBLAog......JHtBLkN9YCk7CiB9CiA=:8:10)

View file

@ -1,2 +1,2 @@
error: Uncaught Error: Hello world!
error: Uncaught (in promise) Error: Hello world!
at http://localhost:4545/run/inline_js_source_map_2.ts:6:7

View file

@ -1,2 +1,2 @@
error: Uncaught Error: Hello world!
error: Uncaught (in promise) Error: Hello world!
at http://localhost:4545/run/inline_js_source_map_2.ts:6:7

View file

@ -1,4 +1,4 @@
error: Uncaught Error: Hello world!
error: Uncaught (in promise) Error: Hello world!
// throw new Error("Hello world!" as string);
^
at http://localhost:4545/run/inline_js_source_map.ts:6:7

View file

@ -1,4 +1,4 @@
error: Uncaught {
error: Uncaught (in promise) {
foo: Error
at file:///[WILDCARD]/main.ts:2:8
}

View file

@ -1,5 +1,5 @@
ok
[WILDCARD]error: Uncaught PermissionDenied: Requires env access to "NOT_NODE_DEBUG", run again with the --allow-env flag
[WILDCARD]error: Uncaught (in promise) PermissionDenied: Requires env access to "NOT_NODE_DEBUG", run again with the --allow-env flag
Deno.env.get("NOT_NODE_DEBUG");
^
at [WILDCARD]

View file

@ -1,3 +1,4 @@
DEBUG RS - [WILDCARD] - Config file found at '[WILDCARD]deno.jsonc'
[WILDCARD]
ok
[WILDCARD]

View file

@ -1,3 +1,4 @@
[WILDCARD]package.json auto-discovery is disabled
[WILDCARD]
success
[WILDCARD]

View file

@ -4,3 +4,4 @@ this
is
a
test
[WILDCARD]

View file

@ -3,10 +3,10 @@ Uncaught error from ./test/no_check.ts FAILED
ERRORS
./test/no_check.ts (uncaught error)
error: TypeError: Cannot read properties of undefined (reading 'fn')
error: (in promise) TypeError: Cannot read properties of undefined (reading 'fn')
Deno.test();
^
at [WILDCARD]/test/no_check.ts:1:6
at [WILDCARD]
This error was not caught from a test and caused the test runner to fail on the referenced module.
It most likely originated from a dangling promise, event/timeout handler or top-level code.

View file

@ -39,7 +39,7 @@ error: Error: bar 3 message
at [WILDCARD]/test/uncaught_errors_2.ts:7:9
./test/uncaught_errors_3.ts (uncaught error)
error: Error: baz
error: (in promise) Error: baz
throw new Error("baz");
^
at [WILDCARD]/test/uncaught_errors_3.ts:1:7

View file

@ -4,4 +4,5 @@ console.log("Starting the child worker");
setTimeout(() => {
console.log("The child worker survived the death of the parent!!!");
Deno.exit(1);
}, 2000);

View file

@ -1,10 +1,10 @@
error: Uncaught (in worker "") Error: foo
error: Uncaught (in worker "") (in promise) Error: foo
throw new Error("foo");
^
at foo ([WILDCARD]/error.ts:2:9)
at [WILDCARD]/error.ts:5:1
{
message: "Uncaught Error: foo",
message: "Uncaught (in promise) Error: foo",
filename: "[WILDCARD]/error.ts",
lineno: 2,
colno: 9

View file

@ -94,7 +94,10 @@ Deno.test({
resolve(e.message);
};
assertMatch(await promise as string, /Uncaught Error: Thrown error/);
assertMatch(
await promise as string,
/Uncaught \(in promise\) Error: Thrown error/,
);
throwingWorker.terminate();
},
});

View file

@ -1,4 +1,4 @@
[WILDCARD]error: Uncaught (in worker "bar") Error: foo[WILDCARD]
[WILDCARD]error: Uncaught (in worker "bar") (in promise) Error: foo[WILDCARD]
at foo ([WILDCARD])
at [WILDCARD]
error: Uncaught (in promise) Error: Unhandled error in child worker.

View file

@ -1,4 +1,4 @@
[WILDCARD]error: Uncaught (in worker "bar") Error: foo[WILDCARD]
[WILDCARD]error: Uncaught (in worker "bar") (in promise) Error: foo[WILDCARD]
throw new Error("foo");
^
at foo ([WILDCARD]/workers/error.ts:[WILDCARD])

View file

@ -6,7 +6,6 @@
// and impossible logic branches based on what Deno currently supports.
const core = globalThis.Deno.core;
const ops = core.ops;
import * as webidl from "ext:deno_webidl/00_webidl.js";
import DOMException from "ext:deno_web/01_dom_exception.js";
import { createFilteredInspectProxy } from "ext:deno_console/01_console.js";
@ -1494,7 +1493,7 @@ function reportException(error) {
});
// Avoid recursing `reportException()` via error handlers more than once.
if (reportExceptionStackedCalls > 1 || globalThis_.dispatchEvent(event)) {
ops.op_dispatch_exception(error);
core.reportUnhandledException(error);
}
reportExceptionStackedCalls--;
}

View file

@ -9,25 +9,6 @@ use deno_core::error::JsError;
use deno_core::error::JsStackFrame;
use std::fmt::Write as _;
/// Compares all properties of JsError, except for JsError::cause.
/// This function is used to detect that 2 JsError objects in a JsError::cause
/// chain are identical, ie. there is a recursive cause.
/// 01_console.js, which also detects recursive causes, can use JS object
/// comparisons to compare errors. We don't have access to JS object identity in
/// format_js_error().
fn errors_are_equal_without_cause(a: &JsError, b: &JsError) -> bool {
a.name == b.name
&& a.message == b.message
&& a.stack == b.stack
// `a.cause == b.cause` omitted, because it is absent in recursive errors,
// despite the error being identical to a previously seen one.
&& a.exception_message == b.exception_message
&& a.frames == b.frames
&& a.source_line == b.source_line
&& a.source_line_frame_index == b.source_line_frame_index
&& a.aggregated == b.aggregated
}
#[derive(Debug, Clone)]
struct ErrorReference<'a> {
from: &'a JsError,
@ -191,10 +172,7 @@ fn find_recursive_cause(js_error: &JsError) -> Option<ErrorReference> {
while let Some(cause) = &current_error.cause {
history.push(current_error);
if let Some(seen) = history
.iter()
.find(|&el| errors_are_equal_without_cause(el, cause.as_ref()))
{
if let Some(seen) = history.iter().find(|&el| cause.is_same_error(el)) {
return Some(ErrorReference {
from: current_error,
to: seen,
@ -246,7 +224,7 @@ fn format_js_error_inner(
s.push_str(&js_error.exception_message);
if let Some(circular) = &circular {
if errors_are_equal_without_cause(js_error, circular.reference.to) {
if js_error.is_same_error(circular.reference.to) {
write!(s, " {}", cyan(format!("<ref *{}>", circular.index))).unwrap();
}
}
@ -281,9 +259,7 @@ fn format_js_error_inner(
if let Some(cause) = &js_error.cause {
let is_caused_by_circular = circular
.as_ref()
.map(|circular| {
errors_are_equal_without_cause(circular.reference.from, js_error)
})
.map(|circular| js_error.is_same_error(circular.reference.from))
.unwrap_or(false);
let error_string = if is_caused_by_circular {

View file

@ -9,12 +9,8 @@ const internals = globalThis.__bootstrap.internals;
const primordials = globalThis.__bootstrap.primordials;
const {
ArrayPrototypeFilter,
ArrayPrototypeIndexOf,
ArrayPrototypeIncludes,
ArrayPrototypeMap,
ArrayPrototypePush,
ArrayPrototypeShift,
ArrayPrototypeSplice,
DateNow,
Error,
ErrorPrototype,
@ -27,13 +23,9 @@ const {
ObjectSetPrototypeOf,
PromisePrototypeThen,
PromiseResolve,
SafeWeakMap,
Symbol,
SymbolIterator,
TypeError,
WeakMapPrototypeDelete,
WeakMapPrototypeGet,
WeakMapPrototypeSet,
} = primordials;
import * as util from "ext:runtime/06_util.js";
import * as event from "ext:deno_web/02_event.js";
@ -328,7 +320,6 @@ function runtimeStart(
target,
) {
core.setMacrotaskCallback(timers.handleTimerMacrotask);
core.setMacrotaskCallback(promiseRejectMacrotaskCallback);
core.setWasmStreamingCallback(fetch.handleWasmStreaming);
core.setReportExceptionCallback(event.reportException);
ops.op_set_format_exception_callback(formatException);
@ -340,91 +331,38 @@ function runtimeStart(
core.setBuildInfo(target);
}
const pendingRejections = [];
const pendingRejectionsReasons = new SafeWeakMap();
function promiseRejectCallback(type, promise, reason) {
switch (type) {
case 0: {
ops.op_store_pending_promise_rejection(promise, reason);
ArrayPrototypePush(pendingRejections, promise);
WeakMapPrototypeSet(pendingRejectionsReasons, promise, reason);
break;
}
case 1: {
ops.op_remove_pending_promise_rejection(promise);
const index = ArrayPrototypeIndexOf(pendingRejections, promise);
if (index > -1) {
ArrayPrototypeSplice(pendingRejections, index, 1);
WeakMapPrototypeDelete(pendingRejectionsReasons, promise);
}
break;
}
default:
return false;
}
return !!globalThis_.onunhandledrejection ||
event.listenerCount(globalThis_, "unhandledrejection") > 0 ||
typeof internals.nodeProcessUnhandledRejectionCallback !== "undefined";
}
function promiseRejectMacrotaskCallback() {
// We have no work to do, tell the runtime that we don't
// need to perform microtask checkpoint.
if (pendingRejections.length === 0) {
return undefined;
}
while (pendingRejections.length > 0) {
const promise = ArrayPrototypeShift(pendingRejections);
const hasPendingException = ops.op_has_pending_promise_rejection(
core.setUnhandledPromiseRejectionHandler(processUnhandledPromiseRejection);
// Notification that the core received an unhandled promise rejection that is about to
// terminate the runtime. If we can handle it, attempt to do so.
function processUnhandledPromiseRejection(promise, reason) {
const rejectionEvent = new event.PromiseRejectionEvent(
"unhandledrejection",
{
cancelable: true,
promise,
);
const reason = WeakMapPrototypeGet(pendingRejectionsReasons, promise);
WeakMapPrototypeDelete(pendingRejectionsReasons, promise);
reason,
},
);
if (!hasPendingException) {
continue;
}
// Note that the handler may throw, causing a recursive "error" event
globalThis_.dispatchEvent(rejectionEvent);
const rejectionEvent = new event.PromiseRejectionEvent(
"unhandledrejection",
{
cancelable: true,
promise,
reason,
},
);
const errorEventCb = (event) => {
if (event.error === reason) {
ops.op_remove_pending_promise_rejection(promise);
}
};
// Add a callback for "error" event - it will be dispatched
// if error is thrown during dispatch of "unhandledrejection"
// event.
globalThis_.addEventListener("error", errorEventCb);
globalThis_.dispatchEvent(rejectionEvent);
globalThis_.removeEventListener("error", errorEventCb);
// If event was not yet prevented, try handing it off to Node compat layer
// (if it was initialized)
if (
!rejectionEvent.defaultPrevented &&
typeof internals.nodeProcessUnhandledRejectionCallback !== "undefined"
) {
internals.nodeProcessUnhandledRejectionCallback(rejectionEvent);
}
// If event was not prevented (or "unhandledrejection" listeners didn't
// throw) we will let Rust side handle it.
if (rejectionEvent.defaultPrevented) {
ops.op_remove_pending_promise_rejection(promise);
}
// If event was not yet prevented, try handing it off to Node compat layer
// (if it was initialized)
if (
!rejectionEvent.defaultPrevented &&
typeof internals.nodeProcessUnhandledRejectionCallback !== "undefined"
) {
internals.nodeProcessUnhandledRejectionCallback(rejectionEvent);
}
return true;
// If event was not prevented (or "unhandledrejection" listeners didn't
// throw) we will let Rust side handle it.
if (rejectionEvent.defaultPrevented) {
return true;
}
return false;
}
let hasBootstrapped = false;
@ -523,8 +461,6 @@ function bootstrapMainRuntime(runtimeOptions) {
event.defineEventHandler(globalThis, "unload");
event.defineEventHandler(globalThis, "unhandledrejection");
core.setPromiseRejectCallback(promiseRejectCallback);
runtimeStart(
denoVersion,
v8Version,
@ -642,8 +578,6 @@ function bootstrapWorkerRuntime(
event.defineEventHandler(self, "error", undefined, true);
event.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) => {

View file

@ -182,6 +182,7 @@ impl WebWorkerInternalHandle {
/// This function will set terminated to true, terminate the isolate and close the message channel
pub fn terminate(&mut self) {
self.cancel.cancel();
self.terminate_waker.wake();
// This function can be called multiple times by whomever holds
// the handle. However only a single "termination" should occur so

View file

@ -1,5 +1,4 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use std::rc::Rc;
use std::sync::atomic::AtomicI32;
use std::sync::atomic::Ordering::Relaxed;