Repository navigation
worker_thread can not capture promise error in worker #33834
Copy link
Copy link
Closed
Labels
promisesIssues and PRs related to ECMAScript promises.Issues and PRs related to ECMAScript promises.workerIssues and PRs related to the worker_threads module and Worker API.Issues and PRs related to the worker_threads module and Worker API.
Description
- Version 12.18:
- Platform ox 10.15.5:
- Subsystem:
What steps will reproduce the bug?
const { Worker, isMainThread } = require('worker_threads')
if (isMainThread) {
const fn = () => {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename)
worker.on('message', resolve)
worker.on('error', reject)
worker.on('exit', (code) => {
if (code !== 0)
reject(new Error(`Worker stopped with exit code ${code}`))
})
})
}
(async () => {
try {
await fn()
} catch (err) {
console.log('main thread err:', err.message)
}
})()
} else {
(async () => {
throw new Error('worker thread err')
})()
}How often does it reproduce? Is there a required condition?
What is the expected behavior?
[Running] node "/code/test/workthread.js"
(node:58339) UnhandledPromiseRejectionWarning: Error: worker thread err
at /code/test/workthread.js:24:11
at Object.<anonymous> (/code/test/workthread.js:25:5)
at Module._compile (internal/modules/cjs/loader.js:1200:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
at Module.load (internal/modules/cjs/loader.js:1049:32)
at Function.Module._load (internal/modules/cjs/loader.js:937:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at MessagePort.<anonymous> (internal/main/worker_thread.js:167:24)
at MessagePort.emit (events.js:315:20)
at MessagePort.onmessage (internal/worker/io.js:78:8)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:58339) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:58339) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
[Done] exited with code=0 in 0.081 seconds
What do you see instead?
Additional information
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
promisesIssues and PRs related to ECMAScript promises.Issues and PRs related to ECMAScript promises.workerIssues and PRs related to the worker_threads module and Worker API.Issues and PRs related to the worker_threads module and Worker API.
Activity
benjamingr commentedon Jun 11, 2020
This behavior is by design and is how Node.js handles rejections. You probably want to use
--unhandled-rejections=strictor add aprocess.on('unhandledRejection'handler.For what it's worth this behavior is currently being discussed ( nodejs/TSC#857 )
I'm going to leave this open in case @addaleax has something to add here. Potentially we could dispatch
unhandledRejectionorerroron the worker as well or something similar - but that would diverge from the rest of the project.lundibundi commentedon Jun 11, 2020
The behavior is by design and it is possible to capture unhandled rejection in worker threads.
This is done the same way as for main thread, by capturing
unhandledRejectionevent. If you change you worker code toit will finish the worker upon receiving
unhandledRejectionand you will get that error inworker.on('exit', (code) => {handler. Another option is to just report it via'message'.As for the
IMO this will have to wait on a general agreement for the default behavior of
unhandledRejection's (whether to exit the process by default), otherwise, it will introduce potentially unnecessary differences between main thread and worker threads.Though we could add an option to automatically add such a handler in worker options that would report/error/exit depending on the option.
addaleax commentedon Jun 11, 2020
We have that option already – using this instead of
new Worker(__filename)“fixes” it:benjamingr commentedon Jun 13, 2020
I think this can be closed. @lanjia thank you for the report :] Please feel free to open more issues about behaviors you find surprising in worker_threads we appreciate those!
(As usual, if anyone feels strongly about this or that we should keep discussing - feel free to re-open)
TimDaub commentedon Apr 22, 2021
IMO, this should be default behavior. It's been weeks that I've been confused with the "worker_threads" implementations and why sometimes it just finishes without logging anything. The problem was most of the time that uncaught exceptions are thrown but never reported.
addaleax commentedon Apr 22, 2021
@TimDaub It is the default behavior in Node.js 15+.
TimDaub commentedon Apr 22, 2021
that's great! Thanks