Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

fix(nuxt): allow responding with custom headers from error.vue #8469

Merged
merged 4 commits into from Oct 26, 2022
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 14 additions & 8 deletions packages/nuxt/src/core/runtime/nitro/error.ts
@@ -1,7 +1,8 @@
import { withQuery } from 'ufo'
import type { NitroErrorHandler } from 'nitropack'
import type { H3Error } from 'h3'
import { getRequestHeaders } from 'h3'
import { getRequestHeaders, H3Response } from 'h3'
import { useNitroApp } from '#internal/nitro'
import { normalizeError, isJsonRequest } from '#internal/nitro/utils'

export default <NitroErrorHandler> async function errorhandler (error: H3Error, event) {
Expand Down Expand Up @@ -46,14 +47,15 @@ export default <NitroErrorHandler> 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), {
pi0 marked this conversation as resolved.
Show resolved Hide resolved
headers: getRequestHeaders(event) as Record<string, string>,
redirect: 'manual'
}).catch(() => null)
: null

// Fallback to static rendered error page
if (!html) {
if (!res) {
pi0 marked this conversation as resolved.
Show resolved Hide resolved
const { template } = process.dev
// @ts-ignore
? await import('@nuxt/ui-templates/templates/error-dev.mjs')
Expand All @@ -63,9 +65,13 @@ export default <NitroErrorHandler> 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')
return event.res.end(template(errorObject))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please return string? H3 will add content-type too and also handles sending response string. Reducing req/res dependency

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. though note I just moved this up - this wasn't a change in this pr

Copy link
Member Author

@danielroe danielroe Oct 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just tried - are you sure an error handler supports returning value directly? it seems to hang.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can check. But seems strange because it is a nitro API route right?

}

event.res.setHeader('Content-Type', 'text/html;charset=UTF-8')
event.res.end(html)
event.respondWith(new H3Response(await res.text(), {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

respond with API is not stable yet and might change. Let's use raw methods for now. I will have an idea for a way to simplify and standardized response format for nitro...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good!

headers: res.headers,
status: res.status === 200 ? errorObject.statusCode : res.status,
statusText: res.statusText || errorObject.statusMessage
}))
}