Skip to content

fix(jest-circus): prevent crash when asyncError is undefined for non-Error throws#16003

Open
ashoknarayan wants to merge 14 commits intojestjs:mainfrom
ashoknarayan:patch-1
Open

fix(jest-circus): prevent crash when asyncError is undefined for non-Error throws#16003
ashoknarayan wants to merge 14 commits intojestjs:mainfrom
ashoknarayan:patch-1

Conversation

@ashoknarayan
Copy link
Copy Markdown

Fixes #15996

Handled cases where asyncError can be undefined when a test throws a non-Error value.

  • Added checks before using asyncError in formatNodeAssertErrors.ts and utils.ts
  • Fallback to creating a new Error when asyncError is missing
  • Added a test to cover this scenario

This prevents jest-circus from crashing and ensures the error is reported properly.

@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla bot commented Mar 19, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: ashoknarayan / name: Ashok Narayan (b7365a7)

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 19, 2026

Deploy Preview for jestjs ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit b7365a7
🔍 Latest deploy log https://app.netlify.com/projects/jestjs/deploys/69c7a8436df6b300082c9fa8
😎 Deploy Preview https://deploy-preview-16003--jestjs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 19, 2026

Open in StackBlitz

babel-jest

npm i https://pkg.pr.new/babel-jest@16003

babel-plugin-jest-hoist

npm i https://pkg.pr.new/babel-plugin-jest-hoist@16003

babel-preset-jest

npm i https://pkg.pr.new/babel-preset-jest@16003

create-jest

npm i https://pkg.pr.new/create-jest@16003

@jest/diff-sequences

npm i https://pkg.pr.new/@jest/diff-sequences@16003

expect

npm i https://pkg.pr.new/expect@16003

@jest/expect-utils

npm i https://pkg.pr.new/@jest/expect-utils@16003

jest

npm i https://pkg.pr.new/jest@16003

jest-changed-files

npm i https://pkg.pr.new/jest-changed-files@16003

jest-circus

npm i https://pkg.pr.new/jest-circus@16003

jest-cli

npm i https://pkg.pr.new/jest-cli@16003

jest-config

npm i https://pkg.pr.new/jest-config@16003

@jest/console

npm i https://pkg.pr.new/@jest/console@16003

@jest/core

npm i https://pkg.pr.new/@jest/core@16003

@jest/create-cache-key-function

npm i https://pkg.pr.new/@jest/create-cache-key-function@16003

jest-diff

npm i https://pkg.pr.new/jest-diff@16003

jest-docblock

npm i https://pkg.pr.new/jest-docblock@16003

jest-each

npm i https://pkg.pr.new/jest-each@16003

@jest/environment

npm i https://pkg.pr.new/@jest/environment@16003

jest-environment-jsdom

npm i https://pkg.pr.new/jest-environment-jsdom@16003

@jest/environment-jsdom-abstract

npm i https://pkg.pr.new/@jest/environment-jsdom-abstract@16003

jest-environment-node

npm i https://pkg.pr.new/jest-environment-node@16003

@jest/expect

npm i https://pkg.pr.new/@jest/expect@16003

@jest/fake-timers

npm i https://pkg.pr.new/@jest/fake-timers@16003

@jest/get-type

npm i https://pkg.pr.new/@jest/get-type@16003

@jest/globals

npm i https://pkg.pr.new/@jest/globals@16003

jest-haste-map

npm i https://pkg.pr.new/jest-haste-map@16003

jest-jasmine2

npm i https://pkg.pr.new/jest-jasmine2@16003

jest-leak-detector

npm i https://pkg.pr.new/jest-leak-detector@16003

jest-matcher-utils

npm i https://pkg.pr.new/jest-matcher-utils@16003

jest-message-util

npm i https://pkg.pr.new/jest-message-util@16003

jest-mock

npm i https://pkg.pr.new/jest-mock@16003

@jest/pattern

npm i https://pkg.pr.new/@jest/pattern@16003

jest-phabricator

npm i https://pkg.pr.new/jest-phabricator@16003

jest-regex-util

npm i https://pkg.pr.new/jest-regex-util@16003

@jest/reporters

npm i https://pkg.pr.new/@jest/reporters@16003

jest-resolve

npm i https://pkg.pr.new/jest-resolve@16003

jest-resolve-dependencies

npm i https://pkg.pr.new/jest-resolve-dependencies@16003

jest-runner

npm i https://pkg.pr.new/jest-runner@16003

jest-runtime

npm i https://pkg.pr.new/jest-runtime@16003

@jest/schemas

npm i https://pkg.pr.new/@jest/schemas@16003

jest-snapshot

npm i https://pkg.pr.new/jest-snapshot@16003

@jest/snapshot-utils

npm i https://pkg.pr.new/@jest/snapshot-utils@16003

@jest/source-map

npm i https://pkg.pr.new/@jest/source-map@16003

@jest/test-result

npm i https://pkg.pr.new/@jest/test-result@16003

@jest/test-sequencer

npm i https://pkg.pr.new/@jest/test-sequencer@16003

@jest/transform

npm i https://pkg.pr.new/@jest/transform@16003

@jest/types

npm i https://pkg.pr.new/@jest/types@16003

jest-util

npm i https://pkg.pr.new/jest-util@16003

jest-validate

npm i https://pkg.pr.new/jest-validate@16003

jest-watcher

npm i https://pkg.pr.new/jest-watcher@16003

jest-worker

npm i https://pkg.pr.new/jest-worker@16003

pretty-format

npm i https://pkg.pr.new/pretty-format@16003

commit: b7365a7

@ashoknarayan
Copy link
Copy Markdown
Author

Hi @alex-all3dp, I’ve implemented the fixes described for this issue. However, I’m running into some CI failures related to the new test I added and I’m not fully sure what’s going wrong there.

Could you please take a look and let me know if I’m missing something in how the test should be structured? I tried to follow the existing patterns, but I might have overlooked something.

Thanks!

@alex-all3dp
Copy link
Copy Markdown

Hi @ashoknarayan, thanks for picking this up! The logic changes in formatNodeAssertErrors.ts and utils.ts look correct.

The CI failures are all coming from the new test file. The import '../mocks/testUtils' resolves to a path that doesn't exist in the package, which causes a module-not-found error that takes down the whole shard (which is why unrelated tests in shard 2 are failing too). There are test helpers in jest-circus/src/tests/ that show how to run jest-in-jest style tests, those should point you in the right direction.

Worth noting is that a synchronous throw { status: 403 } won't actually hit the crash path you're fixing. The asyncError is only undefined when the error comes in through an async channel like a done callback or an unhandled subscription, because that's the case where jest-circus never gets to capture the async stack. To cover the fix you'd need a test that replicates that pattern.

One more thing from the original issue worth addressing: Circus.TestError types the second tuple element as Exception (non-optional), but at runtime it can be undefined. Fixing the type definition alongside the logic changes would be the complete fix.

@ashoknarayan
Copy link
Copy Markdown
Author

Hi @alex-all3dp, I’ve addressed the feedback and updated the PR.

  • Fixed the test to follow the existing patterns in jest-circus
  • Added an async test case that reproduces the scenario where asyncError can be undefined
  • Updated the Circus.TestError type to reflect the runtime behavior

All checks are now passing. Would appreciate it if you could take another look when you get a chance. Thanks!

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.

jest-circus crashes with TypeError when test throws a plain object and asyncError is undefined

2 participants