From f3a496214c85b630b092708d859b2053ce44bbe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sat, 30 Jul 2022 16:09:42 +0200 Subject: [PATCH] fix(core): BorrowMutError in nested error (#15352) --- cli/tests/integration/run_tests.rs | 6 ++++++ cli/tests/testdata/nested_error.ts | 3 +++ cli/tests/testdata/nested_error.ts.out | 4 ++++ core/error.rs | 26 +++++++++++--------------- 4 files changed, 24 insertions(+), 15 deletions(-) create mode 100644 cli/tests/testdata/nested_error.ts create mode 100644 cli/tests/testdata/nested_error.ts.out diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs index 29e424aaed..7354dbf1d3 100644 --- a/cli/tests/integration/run_tests.rs +++ b/cli/tests/integration/run_tests.rs @@ -2792,3 +2792,9 @@ itest!(unhandled_rejection_sync_error { args: "run --check unhandled_rejection_sync_error.ts", output: "unhandled_rejection_sync_error.ts.out", }); + +itest!(nested_error { + args: "run nested_error.ts", + output: "nested_error.ts.out", + exit_code: 1, +}); diff --git a/cli/tests/testdata/nested_error.ts b/cli/tests/testdata/nested_error.ts new file mode 100644 index 0000000000..69828e1ca8 --- /dev/null +++ b/cli/tests/testdata/nested_error.ts @@ -0,0 +1,3 @@ +throw { + foo: new Error(), +}; diff --git a/cli/tests/testdata/nested_error.ts.out b/cli/tests/testdata/nested_error.ts.out new file mode 100644 index 0000000000..042a179ff0 --- /dev/null +++ b/cli/tests/testdata/nested_error.ts.out @@ -0,0 +1,4 @@ +error: Uncaught { + foo: Error + at file:///[WILDCARD]testdata/nested_error.ts:2:8 +} diff --git a/core/error.rs b/core/error.rs index f193c13e24..664cb5c0be 100644 --- a/core/error.rs +++ b/core/error.rs @@ -192,20 +192,17 @@ impl JsError { let msg = v8::Exception::create_message(scope, exception); let mut exception_message = None; - // Nest this state borrow. A mutable borrow can occur when accessing `stack` - // in this outer scope, invoking `Error.prepareStackTrace()` which calls - // `op_apply_source_map`. - { - let state_rc = JsRuntime::state(scope); - let state = state_rc.borrow(); - if let Some(format_exception_cb) = &state.js_format_exception_cb { - let format_exception_cb = format_exception_cb.open(scope); - let this = v8::undefined(scope).into(); - let formatted = format_exception_cb.call(scope, this, &[exception]); - if let Some(formatted) = formatted { - if formatted.is_string() { - exception_message = Some(formatted.to_rust_string_lossy(scope)); - } + let state_rc = JsRuntime::state(scope); + + let js_format_exception_cb = + state_rc.borrow().js_format_exception_cb.clone(); + if let Some(format_exception_cb) = js_format_exception_cb { + let format_exception_cb = format_exception_cb.open(scope); + let this = v8::undefined(scope).into(); + let formatted = format_exception_cb.call(scope, this, &[exception]); + if let Some(formatted) = formatted { + if formatted.is_string() { + exception_message = Some(formatted.to_rust_string_lossy(scope)); } } } @@ -263,7 +260,6 @@ impl JsError { let mut source_line = None; let mut source_line_frame_index = None; { - let state_rc = JsRuntime::state(scope); let state = &mut *state_rc.borrow_mut(); // When the stack frame array is empty, but the source location given by