diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs index adaa6d49dd..9c60cc7454 100644 --- a/cli/tests/integration/run_tests.rs +++ b/cli/tests/integration/run_tests.rs @@ -2738,6 +2738,13 @@ itest!(report_error_handled { output: "report_error_handled.ts.out", }); +// Regression test for https://github.com/denoland/deno/issues/15513. +itest!(report_error_end_of_program { + args: "run --quiet report_error_end_of_program.ts", + output: "report_error_end_of_program.ts.out", + exit_code: 1, +}); + itest!(spawn_stdout_inherit { args: "run --quiet --unstable -A spawn_stdout_inherit.ts", output: "spawn_stdout_inherit.ts.out", diff --git a/cli/tests/testdata/report_error_end_of_program.ts b/cli/tests/testdata/report_error_end_of_program.ts new file mode 100644 index 0000000000..cd7ce7f9c8 --- /dev/null +++ b/cli/tests/testdata/report_error_end_of_program.ts @@ -0,0 +1 @@ +reportError(new Error("foo")); diff --git a/cli/tests/testdata/report_error_end_of_program.ts.out b/cli/tests/testdata/report_error_end_of_program.ts.out new file mode 100644 index 0000000000..ecca633893 --- /dev/null +++ b/cli/tests/testdata/report_error_end_of_program.ts.out @@ -0,0 +1,4 @@ +error: Uncaught Error: foo +reportError(new Error("foo")); + ^ + at [WILDCARD]/report_error_end_of_program.ts:1:13 diff --git a/core/runtime.rs b/core/runtime.rs index def38e1eb5..68c3ab0023 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -1156,14 +1156,14 @@ pub(crate) fn exception_to_err_result<'s, T>( ) -> Result { let state_rc = JsRuntime::state(scope); - let is_terminating_exception = scope.is_execution_terminating(); + let was_terminating_execution = scope.is_execution_terminating(); + // If TerminateExecution was called, cancel isolate termination so that the + // exception can be created. Note that `scope.is_execution_terminating()` may + // have returned false if TerminateExecution was indeed called but there was + // no JS to execute after the call. + scope.cancel_terminate_execution(); let mut exception = exception; - - if is_terminating_exception { - // TerminateExecution was called. Cancel isolate termination so that the - // exception can be created.. - scope.cancel_terminate_execution(); - + { // If the termination is the result of a `Deno.core.terminate` call, we want // to use the exception that was passed to it rather than the exception that // was passed to this function. @@ -1191,8 +1191,8 @@ pub(crate) fn exception_to_err_result<'s, T>( ); } - if is_terminating_exception { - // Re-enable exception termination. + if was_terminating_execution { + // Resume exception termination. scope.terminate_execution(); } @@ -3448,7 +3448,7 @@ assertEquals(1, notify_return_value); Deno.core.ops.op_set_promise_reject_callback((type, promise, reason) => { Deno.core.ops.op_promise_reject(); }); - + throw new Error('top level throw'); "#;