From 12808f175be7e249f7c99e0a6e8166ce4f2845e6 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Wed, 26 Oct 2022 10:25:27 +0200 Subject: [PATCH] fix(nuxt): allow responding with custom headers from `error.vue` (#8469) --- packages/nuxt/src/core/runtime/nitro/error.ts | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/nuxt/src/core/runtime/nitro/error.ts b/packages/nuxt/src/core/runtime/nitro/error.ts index 309ae741526..d282491426c 100644 --- a/packages/nuxt/src/core/runtime/nitro/error.ts +++ b/packages/nuxt/src/core/runtime/nitro/error.ts @@ -1,7 +1,7 @@ import { withQuery } from 'ufo' import type { NitroErrorHandler } from 'nitropack' -import type { H3Error } from 'h3' -import { getRequestHeaders } from 'h3' +import { H3Error, setResponseHeader, getRequestHeaders } from 'h3' +import { useNitroApp } from '#internal/nitro' import { normalizeError, isJsonRequest } from '#internal/nitro/utils' export default async function errorhandler (error: H3Error, event) { @@ -46,14 +46,15 @@ export default async function errorhandler (error: H3Error, // HTML response (via SSR) const isErrorPage = event.req.url?.startsWith('/__nuxt_error') - let html = !isErrorPage - ? await $fetch(withQuery('/__nuxt_error', errorObject), { - headers: getRequestHeaders(event) as HeadersInit + const res = !isErrorPage + ? await useNitroApp().localFetch(withQuery('/__nuxt_error', errorObject), { + headers: getRequestHeaders(event) as Record, + redirect: 'manual' }).catch(() => null) : null // Fallback to static rendered error page - if (!html) { + if (!res) { const { template } = process.dev // @ts-ignore ? await import('@nuxt/ui-templates/templates/error-dev.mjs') @@ -63,9 +64,22 @@ export default async function errorhandler (error: H3Error, // TODO: Support `message` in template (errorObject as any).description = errorObject.message } - html = template(errorObject) + event.res.setHeader('Content-Type', 'text/html;charset=UTF-8') + event.res.end(template(errorObject)) + return + } + + for (const [header, value] of res.headers.entries()) { + setResponseHeader(event, header, value) + } + + if (res.status && res.status !== 200) { + event.res.statusCode = res.status + } + + if (res.statusText) { + event.res.statusMessage = res.statusText } - event.res.setHeader('Content-Type', 'text/html;charset=UTF-8') - event.res.end(html) + event.res.end(await res.text()) }