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