From 733b781bab5dcdcaecf85fa921660b2aab061397 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:59:26 -0800 Subject: [PATCH] fix: ensure lint worker errors aren't silenced (#75766) Errors thrown by the lint worker would only surface the error if `JEST_WORKER_ID` is present. This check was not reliably truthy in all cases (eg, when run with the vercel CLI, `JEST_WORKER_ID` wasn't present) which meant the build would fail with no helpful error message. Outside of that, it was a brittle check because if jest-worker ever changed or removed this env, or we replaced the underlying worker library, this would start failing. This updates the check to be a more explicit env variable that we control. Fixes NEXT-3994 --- packages/next/src/lib/verify-typescript-setup.ts | 2 +- packages/next/src/lib/worker.ts | 3 ++- test/production/app-dir/build-output/index.test.ts | 12 ++++++------ .../app-dir/worker-restart/worker-restart.test.ts | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/next/src/lib/verify-typescript-setup.ts b/packages/next/src/lib/verify-typescript-setup.ts index 56641078bceb17..639531d5670041 100644 --- a/packages/next/src/lib/verify-typescript-setup.ts +++ b/packages/next/src/lib/verify-typescript-setup.ts @@ -164,7 +164,7 @@ export async function verifyTypeScriptSetup({ */ // we are in a worker, print the error message and exit the process - if (process.env.JEST_WORKER_ID) { + if (process.env.IS_NEXT_WORKER) { if (err instanceof Error) { console.error(err.message) } else { diff --git a/packages/next/src/lib/worker.ts b/packages/next/src/lib/worker.ts index 1adddc8b418d4a..cb5648573ec150 100644 --- a/packages/next/src/lib/worker.ts +++ b/packages/next/src/lib/worker.ts @@ -50,6 +50,7 @@ export class Worker { env: { ...((farmOptions.forkOptions?.env || {}) as any), ...process.env, + IS_NEXT_WORKER: 'true', } as any, }, maxRetries: 0, @@ -75,7 +76,7 @@ export class Worker { worker._child?.on('exit', (code, signal) => { if ((code || (signal && signal !== 'SIGINT')) && this._worker) { logger.error( - `Static worker exited with code: ${code} and signal: ${signal}` + `Next.js build worker exited with code: ${code} and signal: ${signal}` ) // if a child process doesn't exit gracefully, we want to bubble up the exit code to the parent process diff --git a/test/production/app-dir/build-output/index.test.ts b/test/production/app-dir/build-output/index.test.ts index 7ec57aa6e47a89..1d041e340a00a7 100644 --- a/test/production/app-dir/build-output/index.test.ts +++ b/test/production/app-dir/build-output/index.test.ts @@ -42,7 +42,7 @@ describe('production - app dir - build output', () => { it('should log errors not caught by the worker without terminating the process', async () => { expect(output).toContain('Error: Boom') - expect(output).not.toContain('Static worker exited with code: 78') + expect(output).not.toContain('Next.js build worker exited with code: 78') const $ = await next.render$('/uncaught-error') expect($('#sentinel').text()).toEqual('at buildtime') @@ -66,7 +66,7 @@ describe('production - app dir - build output', () => { const { cliOutput } = await next.build() await next.deleteFile('app/out-of-band-dynamic-api/page.tsx') - expect(cliOutput).toContain('Static worker exited with code: 78') + expect(cliOutput).toContain('Next.js build worker exited with code: 78') }) it('should fail the build if you use a dynamic API outside of a render context - headers', async () => { @@ -87,7 +87,7 @@ describe('production - app dir - build output', () => { const { cliOutput } = await next.build() await next.deleteFile('app/out-of-band-dynamic-api/page.tsx') - expect(cliOutput).toContain('Static worker exited with code: 78') + expect(cliOutput).toContain('Next.js build worker exited with code: 78') }) it('should fail the build if you use a dynamic API outside of a render context - searchParams', async () => { @@ -106,7 +106,7 @@ describe('production - app dir - build output', () => { const { cliOutput } = await next.build() await next.deleteFile('app/out-of-band-dynamic-api/page.tsx') - expect(cliOutput).toContain('Static worker exited with code: 78') + expect(cliOutput).toContain('Next.js build worker exited with code: 78') }) it('should fail the build if you use a dynamic API outside of a render context - redirect', async () => { @@ -127,7 +127,7 @@ describe('production - app dir - build output', () => { const { cliOutput } = await next.build() await next.deleteFile('app/out-of-band-dynamic-api/page.tsx') - expect(cliOutput).toContain('Static worker exited with code: 78') + expect(cliOutput).toContain('Next.js build worker exited with code: 78') }) it('should fail the build if you use a dynamic API outside of a render context - notFound', async () => { @@ -148,6 +148,6 @@ describe('production - app dir - build output', () => { const { cliOutput } = await next.build() await next.deleteFile('app/out-of-band-dynamic-api/page.tsx') - expect(cliOutput).toContain('Static worker exited with code: 78') + expect(cliOutput).toContain('Next.js build worker exited with code: 78') }) }) diff --git a/test/production/app-dir/worker-restart/worker-restart.test.ts b/test/production/app-dir/worker-restart/worker-restart.test.ts index 5b58609e946651..91843e4651cc73 100644 --- a/test/production/app-dir/worker-restart/worker-restart.test.ts +++ b/test/production/app-dir/worker-restart/worker-restart.test.ts @@ -56,7 +56,7 @@ describe('worker-restart', () => { const output = stdout + stderr expect(output).toContain( - 'Static worker exited with code: null and signal: SIGKILL' + 'Next.js build worker exited with code: null and signal: SIGKILL' ) }) })