diff --git a/.changeset/violet-drinks-film.md b/.changeset/violet-drinks-film.md new file mode 100644 index 000000000000..20098137fc6d --- /dev/null +++ b/.changeset/violet-drinks-film.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes DomException errors not being handled properly diff --git a/packages/astro/e2e/errors.test.js b/packages/astro/e2e/errors.test.js index 825fc7a9224c..600acd95b779 100644 --- a/packages/astro/e2e/errors.test.js +++ b/packages/astro/e2e/errors.test.js @@ -125,4 +125,10 @@ test.describe('Error display', () => { const message = (await getErrorOverlayContent(page)).message; expect(message).toMatch('can only be used in'); }); + + test('can handle DomException errors', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/dom-exception'), { waitUntil: 'networkidle' }); + const message = (await getErrorOverlayContent(page)).message; + expect(message).toMatch('The operation was aborted due to timeout'); + }); }); diff --git a/packages/astro/e2e/fixtures/errors/src/pages/dom-exception.astro b/packages/astro/e2e/fixtures/errors/src/pages/dom-exception.astro new file mode 100644 index 000000000000..99a5322d9979 --- /dev/null +++ b/packages/astro/e2e/fixtures/errors/src/pages/dom-exception.astro @@ -0,0 +1,3 @@ +--- +await fetch("https://example.com/", {signal: AbortSignal.timeout(5)}) +--- diff --git a/packages/astro/src/core/errors/dev/utils.ts b/packages/astro/src/core/errors/dev/utils.ts index c151b55cd712..341c815a6762 100644 --- a/packages/astro/src/core/errors/dev/utils.ts +++ b/packages/astro/src/core/errors/dev/utils.ts @@ -26,7 +26,9 @@ export function collectErrorMetadata(e: any, rootFolder?: URL | undefined): Erro err.forEach((error) => { if (e.stack) { const stackInfo = collectInfoFromStacktrace(e); - error.stack = stripAnsi(stackInfo.stack); + try { + error.stack = stripAnsi(stackInfo.stack); + } catch {} error.loc = stackInfo.loc; error.plugin = stackInfo.plugin; error.pluginCode = stackInfo.pluginCode; @@ -72,7 +74,11 @@ export function collectErrorMetadata(e: any, rootFolder?: URL | undefined): Erro // Strip ANSI for `message` property. Note that ESBuild errors may not have the property, // but it will be handled and added below, which is already ANSI-free if (error.message) { - error.message = stripAnsi(error.message); + try { + error.message = stripAnsi(error.message); + } catch { + // Setting `error.message` can fail here if the message is read-only, which for the vast majority of cases will never happen, however some somewhat obscure cases can cause this to happen. + } } }); @@ -84,7 +90,9 @@ export function collectErrorMetadata(e: any, rootFolder?: URL | undefined): Erro // ESBuild can give us a slightly better error message than the one in the error, so let's use it if (text) { - err[i].message = text; + try { + err[i].message = text; + } catch {} } if (location) {