Skip to content
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

chore: fail test suite if node encounters unhandled promise rejection #5061

Merged
merged 8 commits into from
Jan 14, 2022

Conversation

karanbirsingh
Copy link
Contributor

@karanbirsingh karanbirsingh commented Jan 14, 2022

Details

We have a test that is silently failing because of an unhandled promise rejection. Here are snippets from recent logs. injector-controller is failing (missing an extra InjectionCompleted setup):

PASS unit tests src/tests/unit/tests/background/injector-controller.test.ts
(node:1705) UnhandledPromiseRejectionWarning: Error: expect(received).toBe(expected) // Object.is equality

...

(node:1705) 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: 40)

This PR tries the suggested CLI flag so that our test suite will fail when this happens. Once we have a commit whose associated build fails, I will follow up with a fix for the unit test(s) in this same PR so we can stay green.

The CLI flag appropriately fails the test suite, but I had trouble associating the error with the right test. Debugging updates:

  • only adding --unhandled-rejections=strict fails the test suite, but it's hard to associate the error with the right test. The process completes before listing the name of the failing test. Locally on Windows + node v14.18.2 I see explicit 'FAIL' for the appropriate test; even with 'runInBand' , the process exists after listing the name of the test that failed.
  • also adding await new Promise(jest.nextTick) after each test produces the same log output as above
  • @dbjorge helped resolve this in chore: avoid silent test failures by flushing Promises after each test #5066 by flushing promises after each test without an explicit catch block. That PR will give us better logging if this flag is triggered.
Motivation

Unhandled promise rejections should be treated as test failures.

Context

At first I am updating the unit tests with minimal refactoring to make sure we can get green. It would be good to simplify the tests that were affected by this; they were difficult to debug.

Pull request checklist

  • Addresses an existing issue: #0000
  • Ran yarn fastpass
  • Added/updated relevant unit test(s) (and ran yarn test)
  • Verified code coverage for the changes made. Check coverage report at: <rootDir>/test-results/unit/coverage
  • PR title AND final merge commit title both start with a semantic tag (fix:, chore:, feat(feature-name):, refactor:). See CONTRIBUTING.md.
  • (UI changes only) Added screenshots/GIFs to description above
  • (UI changes only) Verified usability with NVDA/JAWS

@karanbirsingh karanbirsingh requested a review from a team as a code owner January 14, 2022 18:01
@karanbirsingh karanbirsingh changed the title chore: fail test suite if node encountered unhandled promise rejection chore: fail test suite if node encounters unhandled promise rejection Jan 14, 2022
…nimal fix for now to see if other tests are affected by new flag)
…lace the static config list with something else; this was difficult to grok
@karanbirsingh karanbirsingh merged commit 477a147 into microsoft:main Jan 14, 2022
dbjorge added a commit that referenced this pull request Jan 14, 2022
#5066)

#### Details

This PR adds a new setup step to each of our test suites which forces Jest to flush all `Promise`s in a globally applied `afterEach` fixture.

This forces Jest to flush any pending resolved Promises that a test might have forgotten to handle *before* Jest considers that test to be completed. That way, if a test leaks a Promise, the resulting error message gets logged as a failure in the responsible test and includes a nice, Jest-formatted stack, instead of test "passing" and the error as a Node UnhandledProjmiseRejectionWarning with no stack or test context.

This is intended to work in tandem with #5061, allowing it to go in as a last-resort while mitigating the poor logging that we get if it's actually triggered (by avoiding having it need to trigger in the common case)

##### Motivation

Avoids silent test failures (eg, the one that currently exists in `injector-controller.test.ts`)

##### Context

jestjs/jest#10784 (comment)

#### Pull request checklist
<!-- If a checklist item is not applicable to this change, write "n/a" in the checkbox -->
- [n/a] Addresses an existing issue: #0000
- [x] Ran `yarn fastpass`
- [x] Added/updated relevant unit test(s) (and ran `yarn test`)
- [x] Verified code coverage for the changes made. Check coverage report at: `<rootDir>/test-results/unit/coverage`
- [x] PR title *AND* final merge commit title both start with a semantic tag (`fix:`, `chore:`, `feat(feature-name):`, `refactor:`). See `CONTRIBUTING.md`.
- [n/a] (UI changes only) Added screenshots/GIFs to description above
- [n/a] (UI changes only) Verified usability with NVDA/JAWS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants