mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-19 01:45:53 +00:00
fix(nuxt): use payload error state as source of truth (#6389)
This commit is contained in:
parent
0cbba77011
commit
46f36a4038
@ -1,10 +1,8 @@
|
||||
import { createError as _createError, H3Error } from 'h3'
|
||||
import { useNuxtApp, useState } from '#app'
|
||||
import { toRef } from 'vue'
|
||||
import { useNuxtApp } from '#app'
|
||||
|
||||
export const useError = () => {
|
||||
const nuxtApp = useNuxtApp()
|
||||
return useState('error', () => process.server ? nuxtApp.ssrContext.error : nuxtApp.payload.error)
|
||||
}
|
||||
export const useError = () => toRef(useNuxtApp().payload, 'error')
|
||||
|
||||
export interface NuxtError extends H3Error {}
|
||||
|
||||
@ -14,12 +12,8 @@ export const showError = (_err: string | Error | Partial<NuxtError>) => {
|
||||
try {
|
||||
const nuxtApp = useNuxtApp()
|
||||
nuxtApp.callHook('app:error', err)
|
||||
if (process.server) {
|
||||
nuxtApp.ssrContext.error = nuxtApp.ssrContext.error || err
|
||||
} else {
|
||||
const error = useError()
|
||||
error.value = error.value || err
|
||||
}
|
||||
} catch {
|
||||
throw err
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ if (process.server) {
|
||||
await nuxt.hooks.callHook('app:created', vueApp)
|
||||
} catch (err) {
|
||||
await nuxt.callHook('app:error', err)
|
||||
ssrContext.error = ssrContext.error || err
|
||||
nuxt.payload.error = nuxt.payload.error || err
|
||||
}
|
||||
|
||||
return vueApp
|
||||
|
@ -59,7 +59,8 @@ interface _NuxtApp {
|
||||
res?: CompatibilityEvent['res']
|
||||
runtimeConfig: RuntimeConfig
|
||||
noSSR: boolean
|
||||
error?: any
|
||||
/** whether we are rendering an SSR error */
|
||||
error?: boolean
|
||||
nuxt: _NuxtApp
|
||||
payload: _NuxtApp['payload']
|
||||
teleports?: Record<string, string>
|
||||
@ -70,6 +71,14 @@ interface _NuxtApp {
|
||||
data?: Record<string, any>
|
||||
state?: Record<string, any>
|
||||
rendered?: Function
|
||||
error?: Error | {
|
||||
url: string
|
||||
statusCode: string
|
||||
statusMessage: string
|
||||
message: string
|
||||
description: string
|
||||
data?: any
|
||||
}
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
@ -119,19 +128,19 @@ export function createNuxtApp (options: CreateOptions) {
|
||||
defineGetter(nuxtApp.vueApp, '$nuxt', nuxtApp)
|
||||
defineGetter(nuxtApp.vueApp.config.globalProperties, '$nuxt', nuxtApp)
|
||||
|
||||
if (process.server) {
|
||||
// Expose nuxt to the renderContext
|
||||
if (nuxtApp.ssrContext) {
|
||||
nuxtApp.ssrContext.nuxt = nuxtApp
|
||||
}
|
||||
|
||||
if (process.server) {
|
||||
// Expose to server renderer to create window.__NUXT__
|
||||
nuxtApp.ssrContext = nuxtApp.ssrContext || {} as any
|
||||
nuxtApp.ssrContext.payload = nuxtApp.payload
|
||||
if (nuxtApp.ssrContext.payload) {
|
||||
Object.assign(nuxtApp.payload, nuxtApp.ssrContext.payload)
|
||||
}
|
||||
nuxtApp.ssrContext.payload = nuxtApp.payload
|
||||
|
||||
// Expose client runtime-config to the payload
|
||||
if (process.server) {
|
||||
nuxtApp.payload.config = {
|
||||
public: options.ssrContext.runtimeConfig.public,
|
||||
app: options.ssrContext.runtimeConfig.app
|
||||
|
@ -2,13 +2,14 @@ import { withQuery } from 'ufo'
|
||||
import type { NitroErrorHandler } from 'nitropack'
|
||||
// @ts-ignore TODO
|
||||
import { normalizeError, isJsonRequest } from '#internal/nitro/utils'
|
||||
import { NuxtApp } from '#app'
|
||||
|
||||
export default <NitroErrorHandler> async function errorhandler (_error, event) {
|
||||
// Parse and normalize error
|
||||
const { stack, statusCode, statusMessage, message } = normalizeError(_error)
|
||||
|
||||
// Create an error object
|
||||
const errorObject = {
|
||||
const errorObject: Exclude<NuxtApp['payload']['error'], Error> = {
|
||||
url: event.req.url,
|
||||
statusCode,
|
||||
statusMessage,
|
||||
@ -20,7 +21,7 @@ export default <NitroErrorHandler> async function errorhandler (_error, event) {
|
||||
}
|
||||
|
||||
// Set response code and message
|
||||
event.res.statusCode = errorObject.statusCode
|
||||
event.res.statusCode = errorObject.statusCode as any as number
|
||||
event.res.statusMessage = errorObject.statusMessage
|
||||
|
||||
// Console output
|
||||
@ -36,7 +37,7 @@ export default <NitroErrorHandler> async function errorhandler (_error, event) {
|
||||
}
|
||||
|
||||
// HTML response
|
||||
const url = withQuery('/__nuxt_error', errorObject as any)
|
||||
const url = withQuery('/__nuxt_error', errorObject)
|
||||
const html = await $fetch(url).catch((error) => {
|
||||
console.error('[nitro] Error while generating error response', error)
|
||||
return errorObject.statusMessage
|
||||
|
@ -100,7 +100,7 @@ const getSPARenderer = lazyCachedFunction(async () => {
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
// Whether we're rendering an error page
|
||||
const ssrError = event.req.url?.startsWith('/__nuxt_error') ? useQuery(event) : null
|
||||
const ssrError = event.req.url?.startsWith('/__nuxt_error') ? useQuery(event) as Exclude<NuxtApp['payload']['error'], Error> : null
|
||||
const url = ssrError?.url as string || event.req.url!
|
||||
|
||||
// Initialize ssr context
|
||||
@ -111,9 +111,9 @@ export default eventHandler(async (event) => {
|
||||
res: event.res,
|
||||
runtimeConfig: useRuntimeConfig(),
|
||||
noSSR: !!event.req.headers['x-nuxt-no-ssr'],
|
||||
error: ssrError,
|
||||
error: !!ssrError,
|
||||
nuxt: undefined, /* NuxtApp */
|
||||
payload: undefined
|
||||
payload: ssrError ? { error: ssrError } : undefined
|
||||
}
|
||||
|
||||
// Render app
|
||||
@ -126,8 +126,8 @@ export default eventHandler(async (event) => {
|
||||
if (!_rendered) {
|
||||
return
|
||||
}
|
||||
if (ssrContext.error && !ssrError) {
|
||||
throw ssrContext.error
|
||||
if (ssrContext.payload?.error && !ssrError) {
|
||||
throw ssrContext.payload.error
|
||||
}
|
||||
|
||||
// Render meta
|
||||
|
Loading…
Reference in New Issue
Block a user