diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTests.cs b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTests.cs index 08fc1180c849b..5b41e3a1b0302 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTests.cs @@ -41,7 +41,7 @@ private void UpdateBrowserMainJs() string mainJsPath = Path.Combine(_projectDir!, "main.js"); string mainJsContent = File.ReadAllText(mainJsPath); - mainJsContent = mainJsContent.Replace(".create()", ".withConsoleForwarding().withElementOnExit().withExitCodeLogging().create()"); + mainJsContent = mainJsContent.Replace(".create()", ".withConsoleForwarding().withElementOnExit().withExitCodeLogging().withExitOnUnhandledError().create()"); File.WriteAllText(mainJsPath, mainJsContent); } diff --git a/src/mono/wasm/runtime/run-outer.ts b/src/mono/wasm/runtime/run-outer.ts index eb0a83a12c54a..4ff468fce4bb6 100644 --- a/src/mono/wasm/runtime/run-outer.ts +++ b/src/mono/wasm/runtime/run-outer.ts @@ -57,6 +57,29 @@ class HostBuilder implements DotnetHostBuilder { } } + // internal + withExitOnUnhandledError(): DotnetHostBuilder { + const handler = function fatal_handler(event: Event, error: any) { + event.preventDefault(); + try { + mono_exit(1, error); + } catch (err) { + // no not re-throw from the fatal handler + } + }; + try { + // it seems that emscripten already does the right thing for NodeJs and that there is no good solution for V8 shell. + if (ENVIRONMENT_IS_WEB) { + window.addEventListener("unhandledrejection", (event) => handler(event, event.reason)); + window.addEventListener("error", (event) => handler(event, event.error)); + } + return this; + } catch (err) { + mono_exit(1, err); + throw err; + } + } + // internal withAsyncFlushOnExit(): DotnetHostBuilder { try { diff --git a/src/mono/wasm/runtime/run.ts b/src/mono/wasm/runtime/run.ts index 2dca623792ad4..1e224837222ca 100644 --- a/src/mono/wasm/runtime/run.ts +++ b/src/mono/wasm/runtime/run.ts @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { ENVIRONMENT_IS_WEB, INTERNAL, Module, runtimeHelpers } from "./imports"; +import { ENVIRONMENT_IS_WEB, Module, runtimeHelpers } from "./imports"; import { mono_wasm_wait_for_debugger } from "./debug"; import { abort_startup, mono_wasm_set_main_args } from "./startup"; import cwraps from "./cwraps"; @@ -108,12 +108,14 @@ async function flush_node_streams() { function set_exit_code_and_quit_now(exit_code: number, reason?: any): void { if (runtimeHelpers.ExitStatus) { if (reason && !(reason instanceof runtimeHelpers.ExitStatus)) { - if (reason instanceof Error) - Module.printErr(INTERNAL.mono_wasm_stringify_as_error_with_stack(reason)); - else if (typeof reason == "string") - Module.printErr(reason); - else - Module.printErr(JSON.stringify(reason)); + if (!runtimeHelpers.config.logExitCode) { + if (reason instanceof Error) + Module.printErr(mono_wasm_stringify_as_error_with_stack(reason)); + else if (typeof reason == "string") + Module.printErr(reason); + else + Module.printErr(JSON.stringify(reason)); + } } else { reason = new runtimeHelpers.ExitStatus(exit_code); diff --git a/src/mono/wasm/test-main.js b/src/mono/wasm/test-main.js index bac3f856160c5..8d9c391c98190 100644 --- a/src/mono/wasm/test-main.js +++ b/src/mono/wasm/test-main.js @@ -259,6 +259,7 @@ async function run() { .withVirtualWorkingDirectory(runArgs.workingDirectory) .withEnvironmentVariables(runArgs.environmentVariables) .withDiagnosticTracing(runArgs.diagnosticTracing) + .withExitOnUnhandledError() .withExitCodeLogging() .withElementOnExit(); @@ -266,7 +267,7 @@ async function run() { dotnet .withEnvironmentVariable("NodeJSPlatform", process.platform) .withAsyncFlushOnExit(); - + const modulesToLoad = runArgs.environmentVariables["NPM_MODULES"]; if (modulesToLoad) { dotnet.withModuleConfig({