Skip to content

Commit 834d9d6

Browse files
fix(jest-worker): postMessage error handler in child threads (#14437)
1 parent 642267f commit 834d9d6

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Fixes
66

77
- `[jest-core]` Fix typo in `scheduleAndRun` performance marker ([#14434](https://github.com/jestjs/jest/pull/14434))
8+
- `[jest-worker]` Additional error wrapper for `parentPort.postMessage` to fix unhandled `DataCloneError`. ([#14437](https://github.com/jestjs/jest/pull/14437))
89

910
### Chore & Maintenance
1011

packages/jest-worker/src/workers/__tests__/threadChild.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -365,3 +365,24 @@ it('throws if child is not forked', () => {
365365
messagePort.emit('message', [CHILD_MESSAGE_CALL, true, 'fooThrows', []]);
366366
}).toThrow('_worker_threads.parentPort.postMessage is not a function');
367367
});
368+
369+
it('handle error if `postMessage` throws an error', () => {
370+
messagePort.emit('message', [
371+
CHILD_MESSAGE_INITIALIZE,
372+
true,
373+
'./my-fancy-worker',
374+
]);
375+
376+
jest.mocked(messagePort.postMessage).mockImplementationOnce(() => {
377+
throw mockError;
378+
});
379+
380+
messagePort.emit('message', [CHILD_MESSAGE_CALL, true, 'fooWorks', []]);
381+
expect(jest.mocked(messagePort.postMessage).mock.calls[1][0]).toEqual([
382+
PARENT_MESSAGE_CLIENT_ERROR,
383+
'TypeError',
384+
'Boo',
385+
mockError.stack,
386+
{},
387+
]);
388+
});

packages/jest-worker/src/workers/threadChild.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,14 @@ function reportSuccess(result: unknown) {
112112
throw new Error('Child can only be used on a forked process');
113113
}
114114

115-
parentPort!.postMessage([PARENT_MESSAGE_OK, result]);
115+
try {
116+
parentPort!.postMessage([PARENT_MESSAGE_OK, result]);
117+
} catch (err: any) {
118+
// Handling it here to avoid unhandled `DataCloneError` rejection
119+
// which is hard to distinguish on the parent side
120+
// (such error doesn't have any message or stack trace)
121+
reportClientError(err);
122+
}
116123
}
117124

118125
function reportClientError(error: Error) {

0 commit comments

Comments
 (0)