fix(nuxt): avoid recursive ssr errors (#24399)

This commit is contained in:
Pooya Parsa 2023-11-22 10:58:29 +01:00 committed by GitHub
parent abbcaf6b20
commit 1012dc0dbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 6 deletions

View File

@ -45,14 +45,20 @@ export default <NitroErrorHandler> async function errorhandler (error: H3Error,
return send(event, JSON.stringify(errorObject)) return send(event, JSON.stringify(errorObject))
} }
// Access request headers
const reqHeaders = getRequestHeaders(event)
// Detect to avoid recursion in SSR rendering of errors
const isRenderingError = event.path.startsWith('/__nuxt_error') || !!reqHeaders['x-nuxt-error']
// HTML response (via SSR) // HTML response (via SSR)
const isErrorPage = event.path.startsWith('/__nuxt_error') const res = isRenderingError ? null : await useNitroApp().localFetch(
const res = !isErrorPage withQuery(joinURL(useRuntimeConfig().app.baseURL, '/__nuxt_error'), errorObject),
? await useNitroApp().localFetch(withQuery(joinURL(useRuntimeConfig().app.baseURL, '/__nuxt_error'), errorObject), { {
headers: getRequestHeaders(event) as Record<string, string>, headers: { ...reqHeaders, 'x-nuxt-error': 'true' },
redirect: 'manual' redirect: 'manual'
}).catch(() => null) }
: null ).catch(() => null)
// Fallback to static rendered error page // Fallback to static rendered error page
if (!res) { if (!res) {

View File

@ -814,6 +814,17 @@ describe('errors', () => {
"url": "/__nuxt_error", "url": "/__nuxt_error",
} }
`) `)
it('should not recursively throw an error when there is an error rendering the error page', async () => {
const res = await $fetch('/', {
headers: {
'x-test-recurse-error': 'true',
accept: 'text/html'
}
})
expect(typeof res).toBe('string')
expect(res).toContain('Hello Nuxt 3!')
})
}) })
// TODO: need to create test for webpack // TODO: need to create test for webpack

View File

@ -0,0 +1,5 @@
export default defineNuxtPlugin(async () => {
if (useRequestHeaders(['x-test-recurse-error'])['x-test-recurse-error']) {
await useRequestFetch()('/api/error').catch(() => {})
}
})

View File

@ -0,0 +1,3 @@
export default defineEventHandler(async () => {
throw createError({ statusCode: 400 })
})