summaryrefslogtreecommitdiff
path: root/core/runtime.rs
diff options
context:
space:
mode:
authorud2 <sjx233@qq.com>2023-05-08 06:27:59 +0800
committerGitHub <noreply@github.com>2023-05-08 00:27:59 +0200
commit40987178c4f9baf54599b502f943be76f42d6f85 (patch)
tree30892bb0a95bf68f48b95ef1b90bc94afb169fc1 /core/runtime.rs
parent7e1ae655720de72fd555bb1746bb35f5d17f39f6 (diff)
fix(core): always report the first error on unhandled rejection (#18992)
The root cause of denoland/deno_std#3320, I believe, is that `pending_promise_rejections` is a `HashMap` whose entries are in arbitrary order, and as a result either of the two errors (`AddrInUse` and `TypeError`) may be selected when determining which one to report. I changed the field to a `VecDeque` so that the first error (`AddrInUse` in this case) is always selected.
Diffstat (limited to 'core/runtime.rs')
-rw-r--r--core/runtime.rs19
1 files changed, 18 insertions, 1 deletions
diff --git a/core/runtime.rs b/core/runtime.rs
index 8c78be55b..bb77bb25a 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -1831,7 +1831,7 @@ impl JsRuntime {
.state(tc_scope)
.borrow_mut()
.pending_promise_rejections
- .remove(&promise_global);
+ .retain(|(key, _)| key != &promise_global);
}
}
let promise_global = v8::Global::new(tc_scope, promise);
@@ -4139,6 +4139,23 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
}
#[tokio::test]
+ async fn test_unhandled_rejection_order() {
+ let mut runtime = JsRuntime::new(Default::default());
+ runtime
+ .execute_script_static(
+ "",
+ r#"
+ for (let i = 0; i < 100; i++) {
+ Promise.reject(i);
+ }
+ "#,
+ )
+ .unwrap();
+ let err = runtime.run_event_loop(false).await.unwrap_err();
+ assert_eq!(err.to_string(), "Uncaught (in promise) 0");
+ }
+
+ #[tokio::test]
async fn test_set_promise_reject_callback() {
static PROMISE_REJECT: AtomicUsize = AtomicUsize::new(0);