-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jest gives no indication that test fails because of unhandled promise rejection. #9210
Comments
A workaround for others encountering this problem, or rather, a work around for the difficulty of Jest not liking unhandled rejections:
|
Oh wow ok I've just spent far too long trying to figure out how Jest was even seeing the error it was reporting. Really could do with jest saying something, anything, about how it caught the error. Unhandled error/rejection bugs can be subtle and hard to track down, and often appear when you end up with the worst case async scenario where code is unintentionally executing in the background (e.g. missing return Promise) where it can't be sequenced and errors can't be handled. Having Jest show the error without indicating anything at all about how it caught the error is very confusing, especially since Jest seems to override/ignore any unhandled rejection/exception handlers you add in test. |
@JoeLangewayClear's workaround will suppress these errors, but it's kind of like disabling the engine fault light in your car and claiming you "fixed it" |
I would also like to add that the problem here is not only "no indication", but also the fact that the test fails: I was writing a test for utility function and I need to test that this function handles both successful and failing callbacks passed to it. P.S. |
This is intended, the test should fail on unhandled rejection. Short reasoning here. But nevertheless I agree a hint in the error would be great. |
That sounds reasonable, but is "unhandled rejection" checked at the end of the test or immediately? |
Immediately, I believe this is using Node's native handling mechanism for rejected Promises. However note that this does not mean the test case will be aborted, it will be marked as failed but there is no way to stop the test case function execution early. |
This issue seems related to #5958 |
In node v16 the issue has gotten a lot worse.
|
Is there a way to understand what piece of code is throwing that particular error? |
Getting the same problem today: ❯ node --trace-warnings node_modules/.bin/jest --passWithNoTests --no-cache --runInBand --detectOpenHandles --forceExit --coverage
PASS src/application/context.test.tsx
PASS src/application/provider.test.tsx
Running coverage on untested files...(node:27184) UnhandledPromiseRejectionWarning
at emitUnhandledRejectionWarning (internal/process/promises.js:168:15)
at processPromiseRejections (internal/process/promises.js:247:11)
at processTicksAndRejections (internal/process/task_queues.js:96:32)
(node:27184) 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:27184) [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.
at emitDeprecationWarning (internal/process/promises.js:180:11)
at processPromiseRejections (internal/process/promises.js:249:13)
at processTicksAndRejections (internal/process/task_queues.js:96:32) I'm not using any promise yet. My setup: "devDependencies": {
"@hookform/resolvers": "2.9.1",
"@testing-library/dom": "8.13.0",
"@testing-library/jest-dom": "5.16.4",
"@testing-library/react": "13.3.0",
"@testing-library/user-event": "14.2.0",
"@types/jest": "28.1.1",
"@types/leaflet": "^1.7.11",
"@types/node": "17.0.42",
"@types/react": "18.0.12",
"@types/react-dom": "18.0.5",
"@typescript-eslint/eslint-plugin": "5.27.1",
"@typescript-eslint/parser": "5.27.1",
"@vitejs/plugin-react": "1.3.2",
"eslint": "8.17.0",
"eslint-config-airbnb": "19.0.4",
"eslint-config-airbnb-typescript": "17.0.0",
"eslint-config-prettier": "8.5.0",
"eslint-import-resolver-typescript": "2.7.1",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-jest": "26.5.3",
"eslint-plugin-jsx-a11y": "6.5.1",
"eslint-plugin-prettier": "4.0.0",
"eslint-plugin-react": "7.30.0",
"eslint-plugin-react-hooks": "4.5.0",
"eslint-plugin-testing-library": "5.5.1",
"husky": "8.0.1",
"jest": "28.1.1",
"jest-environment-jsdom": "28.1.1",
"jest-watch-typeahead": "1.1.0",
"lint-staged": "13.0.1",
"prettier": "2.6.2",
"ts-jest": "28.0.4",
"ts-node": "10.8.1",
"typescript": "4.7.3",
"vite": "2.9.12",
"yup": "0.32.11"
}
|
Looks like it goes wrong in promises & async nesting only?
Very minimal reproduction case. The code might look a bit weird like that, but it's sometimes needed to mix async & promises with things like manual timeouts. This is just a minimal repro. |
Hitting this too. There should be a setting to disable this functionality. I tried editing jest-circus/build/globalErrorHandlers.js in place, commenting out the inject and restore, and then jest crashes at the site of the uncaught error that later gets caught. So maybe it's actually a problem with node's detection being too eager? In any case, the function |
When I replace the uncaught function with the below, my tests pass, and my app works just fine. This should be a command line option. const uncaught = error => {
console.error(new Error(`uncaught (but ignoring): ${error.stack}`))
return
;(0, _state.dispatchSync)({
error,
name: 'error',
})
} |
Sure, though this makes all uncaught rejections into acceptable behaviour, but at least it's giving some indication that the error was unhandled 👍 |
Well it's odd, I encounter the same situations in prod and there node doesn't complain about uncaught exceptions or rejections, and I have handlers for them. So it seems that Jest somehow triggers node into not being ok with async catchers? |
@wmertens ah that's an issue as well, jest replacing your own handlers |
Well I'm my case that's not an issue, the handlers are only added in prod and they never fire. |
I created a PR that at least marks uncaught errors with their reason, but it doesn't explain why I'm getting uncaught errors that are clearly caught. |
This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days. |
Here is a comment to show, that this issue is still relevant. Very much so! |
👍🏽 |
Given it's been 4 years since the initial opening of this ticket it may be good to create a reproduction of this in the current state-of-things, in terms of last node LTS and Jest version. |
I've tested the earlier mentioned reproduction case and it seems to still be an issue in Node v20.10.0, Jest v29.3.1. |
Any updates about this bug? this should be critical, it's affecting the coverage in our project (and I believe everybody's) and there is no way to work around it except to just not test it. |
🐛 Bug Report
When Jest fails a test for what it thinks - wrongly - is an unhandled rejection, it does not indicate this at all.
To Reproduce
This code in a test module causes Jest to wrongly think a promise rejection isn't going to be handled.
Output:
Note that nothing in the output conveys the real reason this test failed.
Expected behavior
Something in the output says that Jest failed the test because it can't guarantee that the promise rejection will be handled. For instance, instead of:
something like:
The text was updated successfully, but these errors were encountered: