From 4c7ef6a7273070cbe544549f24a4bebc6e58d637 Mon Sep 17 00:00:00 2001 From: "Sebastian \"Sebbie\" Silbermann" Date: Mon, 9 Dec 2024 18:18:12 +0100 Subject: [PATCH] Ignore-list stack frames in node_modules even if not explicitly ignore-listed by their sourcemaps (#73689) --- .eslintignore | 2 + .prettierignore | 2 + .../next/src/server/patch-error-inspect.ts | 97 ++++++++++++------- .../middleware-errors/index.test.ts | 61 ++++-------- .../app/rsc-error-log-ignore-listed/page.js | 15 ++- .../app/ssr-error-log-ignore-listed/page.js | 15 ++- .../fixtures/default/external-pkg/index.js | 3 + .../default/external-pkg/package.json | 13 +++ .../default/external-pkg/sourcemapped.js | 4 + .../default/external-pkg/sourcemapped.js.map | 1 + .../default/external-pkg/sourcemapped.ts | 6 ++ .../default/internal-pkg/package.json | 3 + .../default/internal-pkg/sourcemapped.js | 4 + .../default/internal-pkg/sourcemapped.js.map | 1 + .../default/internal-pkg/sourcemapped.ts | 6 ++ .../fixtures/default/next.config.js | 1 + .../fixtures/default/package.json | 3 +- .../server-source-maps.test.ts | 31 +++--- 18 files changed, 178 insertions(+), 90 deletions(-) create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/index.js create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/package.json create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.js create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.js.map create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.ts create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.js create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.js.map create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.ts diff --git a/.eslintignore b/.eslintignore index 009437967bb4e..98984d851d1f7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -45,6 +45,8 @@ test/development/basic/hmr/components/parse-error.js packages/next-swc/docs/assets/**/* test/lib/amp-validator-wasm.js test/production/pages-dir/production/fixture/amp-validator-wasm.js +test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.js +test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.js test/e2e/async-modules/amp-validator-wasm.js test/development/next-lint-eslint-formatter-compact/**/*.js diff --git a/.prettierignore b/.prettierignore index 9d358f36aa799..456a590ab8d5c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -47,6 +47,8 @@ bench/nested-deps/components/**/* **/.tina/__generated__/** test/lib/amp-validator-wasm.js test/production/pages-dir/production/fixture/amp-validator-wasm.js +test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.js +test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.js test/e2e/async-modules/amp-validator-wasm.js # turbopack crates diff --git a/packages/next/src/server/patch-error-inspect.ts b/packages/next/src/server/patch-error-inspect.ts index d8e3ef4869ce7..876ca1d0957e5 100644 --- a/packages/next/src/server/patch-error-inspect.ts +++ b/packages/next/src/server/patch-error-inspect.ts @@ -108,8 +108,12 @@ function prepareUnsourcemappedStackTrace( return stack } -function shouldIgnoreListByDefault(file: string): boolean { - return file.startsWith('node:') +function shouldIgnoreListGeneratedFrame(file: string): boolean { + return file.startsWith('node:') || file.includes('node_modules') +} + +function shouldIgnoreListOriginalFrame(file: string): boolean { + return file.includes('node_modules') } /** @@ -143,18 +147,23 @@ function findApplicableSourceMapPayload( } } +interface SourcemappableStackFrame extends StackFrame { + file: NonNullable +} + +/** + * @param frame + * @param sourceMapCache + * @returns The original frame if not sourcemapped. + */ function getSourcemappedFrameIfPossible( - frame: StackFrame, + frame: SourcemappableStackFrame, sourceMapCache: SourceMapCache ): { stack: IgnoreableStackFrame // DEV only code: string | null -} | null { - if (frame.file === null) { - return null - } - +} { const sourceMapCacheEntry = sourceMapCache.get(frame.file) let sourceMapConsumer: SyncSourceMapConsumer let sourceMapPayload: ModernSourceMapPayload @@ -170,7 +179,17 @@ function getSourcemappedFrameIfPossible( nativeFindSourceMap(sourceURL)?.payload ?? bundlerFindSourceMapPayload(sourceURL) if (maybeSourceMapPayload === undefined) { - return null + return { + stack: { + arguments: frame.arguments, + column: frame.column, + file: frame.file, + lineNumber: frame.lineNumber, + methodName: frame.methodName, + ignored: shouldIgnoreListGeneratedFrame(frame.file), + }, + code: null, + } } sourceMapPayload = maybeSourceMapPayload sourceMapConsumer = new SyncSourceMapConsumer( @@ -192,7 +211,17 @@ function getSourcemappedFrameIfPossible( }) if (sourcePosition.source === null) { - return null + return { + stack: { + arguments: frame.arguments, + column: frame.column, + file: frame.file, + lineNumber: frame.lineNumber, + methodName: frame.methodName, + ignored: shouldIgnoreListGeneratedFrame(frame.file), + }, + code: null, + } } const sourceContent: string | null = @@ -209,6 +238,14 @@ function getSourcemappedFrameIfPossible( let ignored = false if (applicableSourceMap === undefined) { console.error('No applicable source map found in sections for frame', frame) + } else if (shouldIgnoreListOriginalFrame(sourcePosition.source)) { + // Externals may be libraries that don't ship ignoreLists. + // This is really taking control away from libraries. + // They should still ship `ignoreList` so that attached debuggers ignore-list their frames. + // TODO: Maybe only ignore library sourcemaps if `ignoreList` is absent? + // Though keep in mind that Turbopack omits empty `ignoreList`. + // So if we establish this convention, we should communicate it to the ecosystem. + ignored = true } else { // TODO: O(n^2). Consider moving `ignoreList` into a Set const sourceIndex = applicableSourceMap.sources.indexOf( @@ -271,34 +308,28 @@ function parseAndSourceMap(error: Error): string { for (const frame of unsourcemappedStack) { if (frame.file === null) { sourceMappedStack += '\n' + frameToString(frame) - } else if (!shouldIgnoreListByDefault(frame.file)) { + } else { const sourcemappedFrame = getSourcemappedFrameIfPossible( - frame, + // We narrowed this earlier by bailing if `frame.file` is null. + frame as SourcemappableStackFrame, sourceMapCache ) - if (sourcemappedFrame === null) { - sourceMappedStack += '\n' + frameToString(frame) - } else { - if ( - process.env.NODE_ENV !== 'production' && - sourcemappedFrame.code !== null && - sourceFrameDEV === null && - // TODO: Is this the right choice? - !sourcemappedFrame.stack.ignored - ) { - sourceFrameDEV = sourcemappedFrame.code - } - if (!sourcemappedFrame.stack.ignored) { - // TODO: Consider what happens if every frame is ignore listed. - sourceMappedStack += '\n' + frameToString(sourcemappedFrame.stack) - } else if (showIgnoreListed) { - sourceMappedStack += - '\n' + dim(frameToString(sourcemappedFrame.stack)) - } + if ( + process.env.NODE_ENV !== 'production' && + sourcemappedFrame.code !== null && + sourceFrameDEV === null && + // TODO: Is this the right choice? + !sourcemappedFrame.stack.ignored + ) { + sourceFrameDEV = sourcemappedFrame.code + } + if (!sourcemappedFrame.stack.ignored) { + // TODO: Consider what happens if every frame is ignore listed. + sourceMappedStack += '\n' + frameToString(sourcemappedFrame.stack) + } else if (showIgnoreListed) { + sourceMappedStack += '\n' + dim(frameToString(sourcemappedFrame.stack)) } - } else if (showIgnoreListed) { - sourceMappedStack += '\n' + dim(frameToString(frame)) } } diff --git a/test/development/middleware-errors/index.test.ts b/test/development/middleware-errors/index.test.ts index 0e8a3011e75b3..56d5a688ff9bc 100644 --- a/test/development/middleware-errors/index.test.ts +++ b/test/development/middleware-errors/index.test.ts @@ -42,26 +42,16 @@ describe('middleware - development errors', () => { ? '\n ⨯ Error: boom' + // TODO(veil): Sourcemap to original name i.e. "default" '\n at __TURBOPACK__default__export__ (middleware.js:3:14)' + - '\n 1 |' + - '\n 2 | export default function () {' + - "\n> 3 | throw new Error('boom')" + - '\n | ^' + - '\n 4 | }' + - '\n' + '\n 1 |' : '\n ⨯ Error: boom' + '\n at default (middleware.js:3:14)' + - // TODO(veil): Should be ignore-listed - '\n at eval (webpack' + '\n 1 |' + ) + expect(stripAnsi(next.cliOutput)).toContain( + '' + + "\n> 3 | throw new Error('boom')" + + '\n | ^' ) - if (isTurbopack) { - // already asserted on codeframe earlier - } else { - expect(stripAnsi(next.cliOutput)).toContain( - '' + - "\n> 3 | throw new Error('boom')" + - '\n | ^' - ) - } }) it('renders the error correctly and recovers', async () => { @@ -104,28 +94,17 @@ describe('middleware - development errors', () => { '\n at throwError (middleware.js:4:14)' + // TODO(veil): Sourcemap to original name i.e. "default" '\n at __TURBOPACK__default__export__ (middleware.js:7:8)' + - "\n 2 | import { NextResponse } from 'next/server'" + - '\n 3 | async function throwError() {' + - "\n> 4 | throw new Error('async boom!')" + - '\n | ^' + - '\n 5 | }' + - '\n 6 | export default function () {' + - '\n 7 | throwError()' + "\n 2 | import { NextResponse } from 'next/server'" : '\n ⨯ unhandledRejection: Error: async boom!' + '\n at throwError (middleware.js:4:14)' + '\n at throwError (middleware.js:7:8)' + - // TODO(veil): Should be ignore-listed - '\n at eval (webpack' + "\n 2 | import { NextResponse } from 'next/server'" + ) + expect(stripAnsi(next.cliOutput)).toContain( + '' + + "\n> 4 | throw new Error('async boom!')" + + '\n | ^' ) - if (isTurbopack) { - // already asserted on codeframe earlier - } else { - expect(stripAnsi(next.cliOutput)).toContain( - '' + - "\n> 4 | throw new Error('async boom!')" + - '\n | ^' - ) - } }) it('does not render the error', async () => { @@ -169,14 +148,15 @@ describe('middleware - development errors', () => { ? '\n ⨯ Error [ReferenceError]: test is not defined' + '\n at eval (middleware.js:4:8)' + '\n at (middleware.js:4:8)' + - // TODO(veil): Should be ignore-listed - '\n at fn (node_modules' + // TODO(veil): Should be sourcemapped + '\n at __TURBOPACK__default__export__ (' : '\n ⨯ Error [ReferenceError]: test is not defined' + // TODO(veil): Redundant and not clickable '\n at eval (file://webpack-internal:///(middleware)/./middleware.js)' + '\n at eval (middleware.js:4:8)' + - // TODO(veil): Should be ignore-listed - '\n at fn (node_modules' + // TODO(veil): Redundant + '\n at eval (middleware.js:4:8)' + + "\n 2 | import { NextResponse } from 'next/server'" ) expect(stripAnsi(next.cliOutput)).toContain( isTurbopack @@ -187,8 +167,7 @@ describe('middleware - development errors', () => { : "\n ⚠ DynamicCodeEvaluationWarning: Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Edge Runtime" + '\nLearn More: https://nextjs.org/docs/messages/edge-dynamic-code-evaluation' + '\n at eval (middleware.js:4:8)' + - // TODO(veil): Should be ignore-listed - '\n at eval (webpack' + "\n 2 | import { NextResponse } from 'next/server'" ) }) diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log-ignore-listed/page.js b/test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log-ignore-listed/page.js index d728da34ae0db..4a89ce30ae4db 100644 --- a/test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log-ignore-listed/page.js +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log-ignore-listed/page.js @@ -1,5 +1,8 @@ import { connection } from 'next/server' -import { run } from 'internal-pkg' +import { run as runInternal } from 'internal-pkg' +import { run as runInternalSourceMapped } from 'internal-pkg/sourcemapped' +import { run as runExternal } from 'external-pkg' +import { run as runExternalSourceMapped } from 'external-pkg/sourcemapped' function logError() { const error = new Error('Boom') @@ -9,6 +12,14 @@ function logError() { export default async function Page() { await connection() - run(() => logError()) + runInternal(function runWithInternal() { + runInternalSourceMapped(function runWithInternalSourceMapped() { + runExternal(function runWithExternal() { + runExternalSourceMapped(function runWithExternalSourceMapped() { + logError() + }) + }) + }) + }) return null } diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/app/ssr-error-log-ignore-listed/page.js b/test/e2e/app-dir/server-source-maps/fixtures/default/app/ssr-error-log-ignore-listed/page.js index 12927684927bf..2e323dedf36ce 100644 --- a/test/e2e/app-dir/server-source-maps/fixtures/default/app/ssr-error-log-ignore-listed/page.js +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/app/ssr-error-log-ignore-listed/page.js @@ -1,5 +1,8 @@ 'use client' -import { run } from 'internal-pkg' +import { run as runInternal } from 'internal-pkg' +import { run as runInternalSourceMapped } from 'internal-pkg/sourcemapped' +import { run as runExternal } from 'external-pkg' +import { run as runExternalSourceMapped } from 'external-pkg/sourcemapped' function logError() { const error = new Error('Boom') @@ -7,6 +10,14 @@ function logError() { } export default function Page() { - run(() => logError()) + runInternal(function runWithInternal() { + runInternalSourceMapped(function runWithInternalSourceMapped() { + runExternal(function runWithExternal() { + runExternalSourceMapped(function runWithExternalSourceMapped() { + logError() + }) + }) + }) + }) return null } diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/index.js b/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/index.js new file mode 100644 index 0000000000000..e9112647a2ba6 --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/index.js @@ -0,0 +1,3 @@ +export function run(fn) { + return fn() +} diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/package.json b/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/package.json new file mode 100644 index 0000000000000..e9a1c7828911e --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/package.json @@ -0,0 +1,13 @@ +{ + "name": "external-pkg", + "private": true, + "type": "module", + "exports": { + ".": { + "default": "./index.js" + }, + "./sourcemapped": { + "default": "./sourcemapped.js" + } + } +} diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.js b/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.js new file mode 100644 index 0000000000000..7ccd4b2a5cbd0 --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.js @@ -0,0 +1,4 @@ +export function run(fn) { + return fn(); +} +//# sourceMappingURL=sourcemapped.js.map \ No newline at end of file diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.js.map b/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.js.map new file mode 100644 index 0000000000000..e614248ca1f1b --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemapped.js","sourceRoot":"","sources":["sourcemapped.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,GAAG,CAAI,EAAS;IAC9B,OAAO,EAAE,EAAE,CAAA;AACb,CAAC"} \ No newline at end of file diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.ts b/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.ts new file mode 100644 index 0000000000000..fec32468ef93f --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.ts @@ -0,0 +1,6 @@ +// Compile with pnpm tsc test/e2e/app-dir/server-source-maps/fixtures/default/external-pkg/sourcemapped.ts --sourceMap --target esnext +// tsc compile errors can be ignored +type Fn = () => T +export function run(fn: Fn): T { + return fn() +} diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/package.json b/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/package.json index 77043bd124e18..59b28b243dc9f 100644 --- a/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/package.json +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/package.json @@ -5,6 +5,9 @@ "exports": { ".": { "default": "./index.js" + }, + "./sourcemapped": { + "default": "./sourcemapped.js" } } } diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.js b/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.js new file mode 100644 index 0000000000000..7ccd4b2a5cbd0 --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.js @@ -0,0 +1,4 @@ +export function run(fn) { + return fn(); +} +//# sourceMappingURL=sourcemapped.js.map \ No newline at end of file diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.js.map b/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.js.map new file mode 100644 index 0000000000000..e614248ca1f1b --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemapped.js","sourceRoot":"","sources":["sourcemapped.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,GAAG,CAAI,EAAS;IAC9B,OAAO,EAAE,EAAE,CAAA;AACb,CAAC"} \ No newline at end of file diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.ts b/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.ts new file mode 100644 index 0000000000000..9697ded7ad03a --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.ts @@ -0,0 +1,6 @@ +// Compile with p tsc test/e2e/app-dir/server-source-maps/fixtures/default/internal-pkg/sourcemapped.ts --sourceMap --target esnext +// tsc compile errors can be ignored +type Fn = () => T +export function run(fn: Fn): T { + return fn() +} diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/next.config.js b/test/e2e/app-dir/server-source-maps/fixtures/default/next.config.js index 2e3b04951d3b6..d262505b67130 100644 --- a/test/e2e/app-dir/server-source-maps/fixtures/default/next.config.js +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/next.config.js @@ -6,6 +6,7 @@ const nextConfig = { dynamicIO: true, serverSourceMaps: true, }, + serverExternalPackages: ['external-pkg'], } module.exports = nextConfig diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/package.json b/test/e2e/app-dir/server-source-maps/fixtures/default/package.json index 77a3e0066f372..9ef23a07391dd 100644 --- a/test/e2e/app-dir/server-source-maps/fixtures/default/package.json +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/package.json @@ -1,5 +1,6 @@ { "dependencies": { - "internal-pkg": "file:./internal-pkg" + "internal-pkg": "file:./internal-pkg", + "external-pkg": "file:./external-pkg" } } diff --git a/test/e2e/app-dir/server-source-maps/server-source-maps.test.ts b/test/e2e/app-dir/server-source-maps/server-source-maps.test.ts index c3fd3a9633bd0..ffdfcf97b58d2 100644 --- a/test/e2e/app-dir/server-source-maps/server-source-maps.test.ts +++ b/test/e2e/app-dir/server-source-maps/server-source-maps.test.ts @@ -10,10 +10,11 @@ function normalizeCliOutput(output: string) { describe('app-dir - server source maps', () => { const dependencies = - // 'link:' is not suitable for this test since this makes internal-pkg + // 'link:' is not suitable for this test since this makes packages // not appear in node_modules. { 'internal-pkg': `file:${path.resolve(__dirname, 'fixtures/default/internal-pkg')}`, + 'external-pkg': `file:${path.resolve(__dirname, 'fixtures/default/external-pkg')}`, } const { skipped, next, isNextDev, isTurbopack } = nextTestSetup({ dependencies, @@ -109,11 +110,15 @@ describe('app-dir - server source maps', () => { ? // TODO(veil): Turbopack resolver bug "Module not found: Can't resolve 'internal-pkg'" : '\nError: Boom' + - '\n at logError (app/ssr-error-log-ignore-listed/page.js:5:16)' + - // TODO(veil): Method name should be "Page" - '\n at logError (app/ssr-error-log-ignore-listed/page.js:10:12)' + - '\n at Page (app/ssr-error-log-ignore-listed/page.js:10:6)' + - '\n 3 |' + '\n at logError (app/ssr-error-log-ignore-listed/page.js:8:16)' + + // TODO(veil): Method name should be "runWithExternalSourceMapped" + '\n at logError (app/ssr-error-log-ignore-listed/page.js:17:10)' + + '\n at runWithExternal (app/ssr-error-log-ignore-listed/page.js:16:32)' + + '\n at runWithInternalSourceMapped (app/ssr-error-log-ignore-listed/page.js:15:18)' + + '\n at runWithInternal (app/ssr-error-log-ignore-listed/page.js:14:28)' + + '\n at Page (app/ssr-error-log-ignore-listed/page.js:13:14)' + + '\n 6 |' + + '\n' ) } else { // TODO: Test `next build` with `--enable-source-maps`. @@ -140,11 +145,15 @@ describe('app-dir - server source maps', () => { ? // TODO(veil): Turbopack resolver bug "Module not found: Can't resolve 'internal-pkg'" : '\nError: Boom' + - '\n at logError (app/rsc-error-log-ignore-listed/page.js:5:16)' + - // TODO(veil): Method name should be "Page" - '\n at logError (app/rsc-error-log-ignore-listed/page.js:12:12)' + - '\n at Page (app/rsc-error-log-ignore-listed/page.js:12:6)' + - '\n 3 |' + '\n at logError (app/rsc-error-log-ignore-listed/page.js:8:16)' + + // TODO(veil): Method name should be "runWithExternalSourceMapped" + '\n at logError (app/rsc-error-log-ignore-listed/page.js:19:10)' + + '\n at runWithExternal (app/rsc-error-log-ignore-listed/page.js:18:32)' + + '\n at runWithInternalSourceMapped (app/rsc-error-log-ignore-listed/page.js:17:18)' + + '\n at runWithInternal (app/rsc-error-log-ignore-listed/page.js:16:28)' + + '\n at Page (app/rsc-error-log-ignore-listed/page.js:15:14)' + + '\n 6 |' + + '\n' ) } else { // TODO: Test `next build` with `--enable-source-maps`.