Skip to content

Unhandled rejections in workers should not fire an error event on the Worker object #12221

@andreubotella

Description

@andreubotella

The HTML spec defines steps for reporting runtime script errors (with the error event) and unhandled promise rejections (with the unhandledrejection event). Both mechanisms are fairly similar, but they differ on what happens when an error or rejection happens inside a dedicated worker and is not caught by the corresponding event. Unhandled promise rejections will simply be reported to the console, as they would in a window agent, and never make it outside of the worker – while script errors will fire an error event to the corresponding Worker object in the parent agent.

Deno doesn't (yet?) implement the unhandledrejection event, and an unhandled rejection on the main thread will kill the process. However, an unhandled rejection in a worker will instead fire an error event on the corresponding Worker object – which shouldn't happen per the spec. Arguably the process should be killed, as it would if it happened on the main thread.

This is causing some worker tests to hang forever in #12222.


Here's a test to compare the behavior in Deno and in browsers.

// main.js
const worker = new Worker(new URL("./worker.js", import.meta.url), {type: "module"});

worker.addEventListener("error", () => {
    console.log("worker.onerror in main thread");
});

window.addEventListener("error", () => {
    console.log("window.onerror in main thread");
});

window.addEventListener("unhandledrejection", () => {
    console.log("window.onunhandledrejection in main thread");
});
// worker.js
self.addEventListener("error", () => {
    console.log("self.onerror in worker");
});

self.addEventListener("unhandledrejection", () => {
    console.log("self.onunhandledrejection in worker");
});

(async () => {
    throw new Error("Error");
})();

All browsers fire the unhandledrejection event inside the worker, report the error, and don't fire any event in the main thread:
image

While Deno will report the error inside the worker, fire the error event on the main thread's worker object, and then die because the error wasn't handled:
image

(This screenshot uses Deno canary – 1.14.1 would panic because of #11342.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working correctlywebrelated to Web APIs

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions