jest: Unhandled Promise Rejection Logging
Do you want to request a feature or report a bug? feature
What is the current behavior?
When writing unit tests that involve promises, if a developer does not return the promise (or use async
/await
), uncaught rejections bubble up to Node’s default unhandledRejection
handler. For example:
That’s fine, except that when running tests locally, because of the way Jest aggressively clears the console as concurrent test suites finish running, Node’s default unhandledRejection
logging sometimes gets cleared off the terminal. I’ve found this to be especially problematic on machines with more CPUs where many tests may be running concurrently.
That can make spotting these errors trickier in development. The default node error handler always prints the message in CI, when Jest isn’t clearing the console at all, but in dev it’s inconsistent.
If the current behavior is a bug, please provide the steps to reproduce and either a repl.it demo through https://repl.it/languages/jest or a minimal repository on GitHub that we can yarn install
and yarn test
.
What is the expected behavior?
It would be great if Jest had a default unhandledRejection
handler baked in that provided the same error message and stack trace formatting we get for other errors. And, more importantly, if the default handler could ensure the error would not get wiped away by any console clearing Jest does in dev.
As a quick fix, I added an unhandledRejection
handler in my Jest setup that logs the error to the console.
But if you guys think this could be useful to other people, I’d be happy to take a stab at implementing a more robust solution in Jest itself!
Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system. Jest v19.0.2 Node v6.9.4 yarn v0.21.3 Mac OS X 10.12.3
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 35
- Comments: 24 (12 by maintainers)
Commits related to this issue
- tests: throw in case we encounter unhandled promise rejection As opposed to just showing a warning that might get eaten in cli when multple jest child processes work in parallel. See https://github.c... — committed to wmde/wikibase-termbox by wiese 6 years ago
- tests: throw in case we encounter unhandled promise rejection As opposed to just showing a warning that might get eaten in cli when multple jest child processes work in parallel. See https://github.c... — committed to wmde/wikibase-termbox by wiese 6 years ago
- tests: throw in case we encounter unhandled promise rejection As opposed to just showing a warning that might get eaten in cli when multple jest child processes work in parallel. See https://github.c... — committed to wmde/wikibase-termbox by wiese 6 years ago
- bridge: throw in case we encounter unhandled rejection in tests As opposed to just showing a warning that might get eaten in cli when multiple jest child processes work in parallel. See https://githu... — committed to wikimedia/mediawiki-extensions-Wikibase by wiese 5 years ago
- Update git submodules * Update Wikibase from branch 'master' to da868c37ebe5f9471d02710a5f0fd532c8b6573c - Merge "bridge: throw in case we encounter unhandled rejection in tests" - bridge: thro... — committed to wikimedia/mediawiki-extensions by deleted user 5 years ago
- Update to @vue/cli v4 Updates were fully automated by following the docs: https://cli.vuejs.org/guide/installation.html#project-dependencies postcss.config.js and jest.config.js required small manua... — committed to wikimedia/wikibase-termbox by jakobw 3 years ago
@FredyC here’s how I avoid the memory leak:
In this snippet I don’t just log the error but I throw it to make sure
jest test
will return a non-zero exit code. This is very useful in a ci context.A small workaround I’ve figured out. Use
setupFiles
configuration option and create a simple file like this. If you need it for a browser, just check out this..Then suddenly all warnings are replaced by nice stack trace 😃
Edit: One caveat is this warning instead. I am not sure what happens with a really large project.
(node:8452) Warning: Possible EventEmitter memory leak detected. 11 unhandledRejection listeners added. Use emitter.setMaxListeners() to increase limit
This seems to have been implemented in Jest 21, and it is extremely annoying. Any asynchronously handled promises that is rejected before having a handler attached makes tests fail. And I don’t find any way to deactive this behaviour.
Any idea of how to overcome this? Thanks.
i think the easiest way to implement something like this is to have a global handler and save all unhandled errors to a test state. then when all tests are done, check the state, if there’s any errors, fail the test and log them
Yeah this is kind of a blocker for me. Here’s a small test to demonstrate the issue:
This test fails in Jest 21.x, but runs fine in Jest 20.x. If I were to catch the exception synchronously (NOT inside a setTimeout), the test passes in Jest 21.x as expected.
This looks like a contrived exception, but in my actual code, I’m having a Promise reject inside of an Express router that I’m testing. I’m testing the router using Supertest, so I have to use
done()
after running assertions on the http response.yea! I remember we already thought about it in the past, but couldn’t implement it because of Jasmine dependency. Now that we started migrating away from jasmine i think it’d be pretty easy to implement!
@stipsan That’s kinda surprising that setting env variable here actually makes it shared between other jest child processes. Not sure how that works really, but good to know 😃
https://github.com/nodejs/node/commit/13db29b2f7f0970c16228790f755262b3617f31e
This seems to have just gotten a lot more important with Jest 20. I’m seeing expectations that are after a
.resolves
like.resolves.isInstanceOf()
just print thisUnhandledPromiseRejectionWarning
and don’t even register with the jest final output that there was a test failure.@ramusus Unfortunately, the best I could do was just downgrade to 20.x. I haven’t looked into updating back to 21.x since Oct though, so maybe things have changed.