oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.31k stars 2.78k forks source link

Uncaught promise rejection in async test causes hang #14624

Open refi64 opened 1 month ago

refi64 commented 1 month ago

What version of Bun is running?

1.1.31-debug

What platform is your computer?

Linux 6.11.0-400.asahi.fc40.aarch64+16k aarch64 unknown

What steps can reproduce the bug?

import {test} from 'bun:test'

test('a', async () => {
  console.log('test start')
  ;(async () => { throw 123 })()
  await Bun.sleep(1)
  console.log('test end')
})

What is the expected behavior?

This should run the test and report a failure.

What do you see instead?

$ BUN_DEBUG_QUIET_LOGS=1 build/debug/bun-debug test ./x.test.js
bun test v1.1.31 (2d0b557f)

x.test.js:
test a start
error: 123
✗ a [3.00ms]

and then it just hangs. This is also reproducible on Bun 1.29.

Additional information

No response

refi64 commented 1 month ago

This is actually "fixed" by defining another async test that runs afterwards, e.g.:

test('b', async () => {
  console.log('test b')
  await Bun.sleep(1)
})

will cause it to no longer hang...but then you run into #14644.

refi64 commented 1 month ago

So https://github.com/oven-sh/bun/pull/13463 fixed hangs for the done callback, with this code in jest.zig's TestRunnerTask.run from https://github.com/oven-sh/bun/commit/886c31f0c5971607cb1777148d805688be6d1b98:

            if (this.reported and this.promise_state != .pending) {
                // An unhandled error was reported.
                // Let's allow any pending work to run, and then move on to the next test.
                this.continueRunningTestsAfterMicrotasksRun();
            }

If I remove the this.promise_state != .pending, then this no longer hangs. I'm not sure why it seems like it was hard-coded to only handle done being called instead?