diff --git a/.changeset/real-dryers-leave.md b/.changeset/real-dryers-leave.md new file mode 100644 index 000000000..4d31e082a --- /dev/null +++ b/.changeset/real-dryers-leave.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix missing stacktraces for Zod errors diff --git a/packages/astro/src/core/errors/dev/utils.ts b/packages/astro/src/core/errors/dev/utils.ts index 28445ba32..29468c7fd 100644 --- a/packages/astro/src/core/errors/dev/utils.ts +++ b/packages/astro/src/core/errors/dev/utils.ts @@ -24,9 +24,13 @@ export function collectErrorMetadata(e: any, rootFolder?: URL | undefined): Erro ? (e.errors as SSRError[]) : [e as SSRError]; - err.forEach((error) => { - if (error.stack) { - error = collectInfoFromStacktrace(e); + err.forEach((error, idx) => { + if (e.stack) { + const stackInfo = collectInfoFromStacktrace(e); + error.stack = stackInfo.stack; + error.loc = stackInfo.loc; + error.plugin = stackInfo.plugin; + error.pluginCode = stackInfo.pluginCode; } // Make sure the file location is absolute, otherwise: @@ -141,15 +145,22 @@ See https://docs.astro.build/en/guides/troubleshooting/#document-or-window-is-no return err.hint; } -function collectInfoFromStacktrace(error: SSRError): SSRError { - if (!error.stack) return error; +type StackInfo = Pick; + +function collectInfoFromStacktrace(error: SSRError & { stack: string }): StackInfo { + let stackInfo: StackInfo = { + stack: error.stack, + plugin: error.plugin, + pluginCode: error.pluginCode, + loc: error.loc, + }; // normalize error stack line-endings to \n - error.stack = normalizeLF(error.stack); + stackInfo.stack = normalizeLF(error.stack); const stackText = stripAnsi(error.stack); // Try to find possible location from stack if we don't have one - if (!error.loc || (!error.loc.column && !error.loc.line)) { + if (!stackInfo.loc || (!stackInfo.loc.column && !stackInfo.loc.line)) { const possibleFilePath = error.loc?.file || error.pluginCode || @@ -168,7 +179,7 @@ function collectInfoFromStacktrace(error: SSRError): SSRError { file = fileURLToPath(file); } catch {} - error.loc = { + stackInfo.loc = { file, line: Number.parseInt(line), column: Number.parseInt(column), @@ -177,17 +188,17 @@ function collectInfoFromStacktrace(error: SSRError): SSRError { } // Derive plugin from stack (if possible) - if (!error.plugin) { - error.plugin = + if (!stackInfo.plugin) { + stackInfo.plugin = /withastro\/astro\/packages\/integrations\/([\w-]+)/gim.exec(stackText)?.at(1) || /(@astrojs\/[\w-]+)\/(server|client|index)/gim.exec(stackText)?.at(1) || undefined; } // Normalize stack (remove `/@fs/` urls, etc) - error.stack = cleanErrorStack(error.stack); + stackInfo.stack = cleanErrorStack(error.stack); - return error; + return stackInfo; } function cleanErrorStack(stack: string) {