Fix: Zod errors missing stacktrace (#7380)

* wip: figure out stack issue, weird JSON stringify bug on zod issue

* refactor: return data instead of mutating

* refactor: remove need for reassignment

* fix: e.stack only

* chore: changeset
This commit is contained in:
Ben Holmes 2023-06-12 17:20:04 -04:00 committed by GitHub
parent 0986a44ddd
commit 1c7b635956
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 12 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fix missing stacktraces for Zod errors

View file

@ -24,9 +24,13 @@ export function collectErrorMetadata(e: any, rootFolder?: URL | undefined): Erro
? (e.errors as SSRError[]) ? (e.errors as SSRError[])
: [e as SSRError]; : [e as SSRError];
err.forEach((error) => { err.forEach((error, idx) => {
if (error.stack) { if (e.stack) {
error = collectInfoFromStacktrace(e); 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: // 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; return err.hint;
} }
function collectInfoFromStacktrace(error: SSRError): SSRError { type StackInfo = Pick<SSRError, 'stack' | 'loc' | 'plugin' | 'pluginCode'>;
if (!error.stack) return error;
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 // normalize error stack line-endings to \n
error.stack = normalizeLF(error.stack); stackInfo.stack = normalizeLF(error.stack);
const stackText = stripAnsi(error.stack); const stackText = stripAnsi(error.stack);
// Try to find possible location from stack if we don't have one // 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 = const possibleFilePath =
error.loc?.file || error.loc?.file ||
error.pluginCode || error.pluginCode ||
@ -168,7 +179,7 @@ function collectInfoFromStacktrace(error: SSRError): SSRError {
file = fileURLToPath(file); file = fileURLToPath(file);
} catch {} } catch {}
error.loc = { stackInfo.loc = {
file, file,
line: Number.parseInt(line), line: Number.parseInt(line),
column: Number.parseInt(column), column: Number.parseInt(column),
@ -177,17 +188,17 @@ function collectInfoFromStacktrace(error: SSRError): SSRError {
} }
// Derive plugin from stack (if possible) // Derive plugin from stack (if possible)
if (!error.plugin) { if (!stackInfo.plugin) {
error.plugin = stackInfo.plugin =
/withastro\/astro\/packages\/integrations\/([\w-]+)/gim.exec(stackText)?.at(1) || /withastro\/astro\/packages\/integrations\/([\w-]+)/gim.exec(stackText)?.at(1) ||
/(@astrojs\/[\w-]+)\/(server|client|index)/gim.exec(stackText)?.at(1) || /(@astrojs\/[\w-]+)\/(server|client|index)/gim.exec(stackText)?.at(1) ||
undefined; undefined;
} }
// Normalize stack (remove `/@fs/` urls, etc) // Normalize stack (remove `/@fs/` urls, etc)
error.stack = cleanErrorStack(error.stack); stackInfo.stack = cleanErrorStack(error.stack);
return error; return stackInfo;
} }
function cleanErrorStack(stack: string) { function cleanErrorStack(stack: string) {