From cac64d4d2f212509783c7abd1bf5cc770ce5f5b7 Mon Sep 17 00:00:00 2001 From: Yaroslav Serhieiev Date: Wed, 9 Jul 2025 09:34:36 +0300 Subject: [PATCH] fix: prevent double teardown on test environment error --- .../environmentTeardownError.test.ts | 21 +++++++++++++++++++ .../EnvironmentWithTeardownError.js | 17 +++++++++++++++ .../environmentTeardownError.test.js | 9 ++++++++ e2e/environment-teardown-error/package.json | 5 +++++ packages/jest-runner/src/runTest.ts | 7 +++++-- 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 e2e/__tests__/environmentTeardownError.test.ts create mode 100644 e2e/environment-teardown-error/EnvironmentWithTeardownError.js create mode 100644 e2e/environment-teardown-error/__tests__/environmentTeardownError.test.js create mode 100644 e2e/environment-teardown-error/package.json diff --git a/e2e/__tests__/environmentTeardownError.test.ts b/e2e/__tests__/environmentTeardownError.test.ts new file mode 100644 index 000000000000..5ed1c0f119a7 --- /dev/null +++ b/e2e/__tests__/environmentTeardownError.test.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import runJest from '../runJest'; + +// This test ensures that if a custom environment's teardown throws, Jest reports the real error, not an internal error. +describe('Environment Teardown Error', () => { + it('reports the error thrown from teardown() in a custom environment', () => { + const {stderr, exitCode} = runJest('environment-teardown-error'); + expect(exitCode).toBe(1); + expect(stderr).toMatch('teardown error from custom environment'); + // Should NOT contain the internal error that was seen in the regression + expect(stderr).not.toMatch( + 'The "object" argument must be of type object. Received null', + ); + }); +}); diff --git a/e2e/environment-teardown-error/EnvironmentWithTeardownError.js b/e2e/environment-teardown-error/EnvironmentWithTeardownError.js new file mode 100644 index 000000000000..e0e0fc85c993 --- /dev/null +++ b/e2e/environment-teardown-error/EnvironmentWithTeardownError.js @@ -0,0 +1,17 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const NodeEnvironment = require('jest-environment-node').default; + +class EnvironmentWithTeardownError extends NodeEnvironment { + async teardown() { + await super.teardown(); + throw new Error('teardown error from custom environment'); + } +} + +module.exports = EnvironmentWithTeardownError; diff --git a/e2e/environment-teardown-error/__tests__/environmentTeardownError.test.js b/e2e/environment-teardown-error/__tests__/environmentTeardownError.test.js new file mode 100644 index 000000000000..fc944407b1c9 --- /dev/null +++ b/e2e/environment-teardown-error/__tests__/environmentTeardownError.test.js @@ -0,0 +1,9 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +test('Environment must tear down with a correct error stack trace', () => {}); diff --git a/e2e/environment-teardown-error/package.json b/e2e/environment-teardown-error/package.json new file mode 100644 index 000000000000..9712a8d46502 --- /dev/null +++ b/e2e/environment-teardown-error/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "testEnvironment": "/EnvironmentWithTeardownError.js" + } +} diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index ccc756fed968..05256db47aa7 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -217,8 +217,11 @@ async function runTestInternal( ); sourcemapSupport.resetRetrieveHandlers(); - await environment.teardown(); - isTornDown = true; + try { + await environment.teardown(); + } finally { + isTornDown = true; + } } };