Skip to content

Commit 75bbab5

Browse files
committed
feat(cli): keep user-land frames in config loading errors
Refine ConfigurationLoadingError formatting to cut the stack at the first internal Node.js / dependency frame instead of the first frame, so that an error thrown at runtime inside a config still shows the offending config line (e.g. `at Object.<anonymous> (webpack.config.js:3:9)`), while internal loader frames remain trimmed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019fDbvnssGbssgK6qCaRBLj
1 parent fbb4e6a commit 75bbab5

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

packages/webpack-cli/src/webpack-cli.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,16 +426,21 @@ class ConfigurationLoadingError extends Error {
426426
// the noise. For module-loading errors (e.g. a `SyntaxError`) `error.stack`
427427
// begins with a code frame (file, line, source and a caret) that points at
428428
// the exact location of the problem — far more useful than `error.message`
429-
// alone. We keep that context (and the Node.js error `code`, e.g.
430-
// `MODULE_NOT_FOUND`) but drop the noisy internal Node.js stack frames.
429+
// alone. We keep that context, any user-land stack frames (e.g. the config
430+
// line that threw) and the Node.js error `code` (e.g. `MODULE_NOT_FOUND`),
431+
// but drop the noisy internal Node.js / dependency stack frames.
431432
static format(error: unknown): string {
432433
if (!(error instanceof Error)) {
433434
return ConfigurationLoadingError.indent(String(error));
434435
}
435436

436437
const lines = (error.stack ?? `${error.name}: ${error.message}`).split("\n");
437-
const firstFrame = lines.findIndex((line) => /^\s*at\s/.test(line));
438-
let details = (firstFrame === -1 ? lines : lines.slice(0, firstFrame)).join("\n").trimEnd();
438+
const isFrame = (line: string): boolean => /^\s*at\s/.test(line);
439+
const isNoise = (line: string): boolean => /node:|node_modules/.test(line);
440+
// Cut from the first internal/dependency frame onwards, keeping the code
441+
// frame and any leading user-land frames above it.
442+
const firstNoise = lines.findIndex((line) => isFrame(line) && isNoise(line));
443+
let details = (firstNoise === -1 ? lines : lines.slice(0, firstNoise)).join("\n").trimEnd();
439444

440445
const { code } = error as NodeJS.ErrnoException;
441446

0 commit comments

Comments
 (0)