Skip to content

fix(test): run cleanup when a teardown hook fails (runner + Bun adapter) - #1346

Closed
sam-goodwin wants to merge 1 commit into
mainfrom
fix/test-teardown-hook-failures
Closed

fix(test): run cleanup when a teardown hook fails (runner + Bun adapter)#1346
sam-goodwin wants to merge 1 commit into
mainfrom
fix/test-teardown-hook-failures

Conversation

@sam-goodwin

Copy link
Copy Markdown
Contributor

Companion to #1341: the Vitest adapter's teardown-ordering fix revealed a broader class — a failing teardown hook silently drops later cleanup, leaking the shared scope and local provider sidecar for the rest of the test process. The other two adapters each had it with a different trigger.

alchemy-test runnerrunAfterAll short-circuited on the first failing hook:

// before: Effect.forEach on the error channel — first failure skips the rest
// after: every afterAll runs; failures aggregate into fileErrors
const exits = yield* Effect.forEach(suite.afterAll, (hook) =>
  Effect.suspend(hook.body).pipe(Effect.timeout(...), Effect.exit),
).pipe(withCapture(ctx.fileLogs));

beforeAll keeps short-circuit semantics (a failed setup invalidates what follows); teardowns all run, matching every mainstream runner's contract.

Test/Bun — probed bun:test empirically: afterAll runs in registration order ✓, and still runs after a failed beforeAll ✓, but the chain stops once a hook throws — skipping the microtask-registered fallback. The adapter now guards user teardowns:

const guardTeardown = (eff) => () =>
  runEff(eff).catch(async (error) => {
    await Effect.runPromise(closeAll); // idempotent
    throw error;                       // still fails the suite
  });

Both regression tests are two-sided and red against the previous code:

  • alchemy-test/test/Runner.test.ts — a file with a failing first afterAll must still run the second (sentinel asserted from the spawned runner's output) and exit non-zero.
  • test/Test/Bun.test.ts — spawns real bun test on a fixture using the public adapter; a shared-scope finalizer sentinel proves the cleanup ran after the throwing user teardown.

…r + Bun adapter)

Companion to #1341's Vitest aroundAll fix — the other two adapters had
the same class of leak, each with a different trigger:

- alchemy-test runner: runAfterAll short-circuited on the first failing
  hook, so a failing teardown assertion dropped every later afterAll —
  including Test.make's fallback that closes the shared scope and local
  provider sidecar. afterAll hooks now all run; failures aggregate.
- Test/Bun: bun:test stops the afterAll chain once a hook throws
  (verified empirically; registration order and afterAll-after-failed-
  beforeAll are fine), skipping the microtask-registered fallback. The
  adapter now guards user teardowns: on failure it runs the idempotent
  cleanup before rethrowing.

Both regression tests are red against the previous code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@alchemy-version-bot

Copy link
Copy Markdown
Contributor

Install the packages built from this commit:

Alchemy

alchemy

bun add https://pkg.ing/alchemy/e4d10d1

@alchemy.run/better-auth

bun add https://pkg.ing/@alchemy.run/better-auth/e4d10d1

@alchemy.run/cloudflare-runtime

bun add https://pkg.ing/@alchemy.run/cloudflare-runtime/e4d10d1

@alchemy.run/frontend-frameworks

bun add https://pkg.ing/@alchemy.run/frontend-frameworks/e4d10d1

@alchemy.run/node-utils

bun add https://pkg.ing/@alchemy.run/node-utils/e4d10d1

@alchemy.run/pr-package

bun add https://pkg.ing/@alchemy.run/pr-package/e4d10d1

@alchemy.run/floci

bun add https://pkg.ing/@alchemy.run/floci/e4d10d1

Distilled

@distilled.cloud/core

bun add https://pkg.ing/@distilled.cloud/core/dd2a322

@distilled.cloud/aws

bun add https://pkg.ing/@distilled.cloud/aws/dd2a322

@distilled.cloud/axiom

bun add https://pkg.ing/@distilled.cloud/axiom/dd2a322

@distilled.cloud/cloudflare

bun add https://pkg.ing/@distilled.cloud/cloudflare/dd2a322

@distilled.cloud/hetzner

bun add https://pkg.ing/@distilled.cloud/hetzner/dd2a322

@distilled.cloud/neon

bun add https://pkg.ing/@distilled.cloud/neon/dd2a322

@distilled.cloud/planetscale

bun add https://pkg.ing/@distilled.cloud/planetscale/dd2a322

@sam-goodwin

Copy link
Copy Markdown
Contributor Author

Folded into #1339.

@sam-goodwin
sam-goodwin deleted the fix/test-teardown-hook-failures branch August 25, 2026 02:44
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.

1 participant