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

fix(nuxt): use payload error state as source of truth #6389

Merged
merged 5 commits into from
Aug 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions packages/nuxt/src/app/composables/error.ts
Original file line number Diff line number Diff line change
@@ -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 {}

Expand All @@ -15,12 +13,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
}
const error = useError()
error.value = error.value || err
} catch {
throw err
}
Expand Down
2 changes: 1 addition & 1 deletion packages/nuxt/src/app/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 18 additions & 9 deletions packages/nuxt/src/app/nuxt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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
pi0 marked this conversation as resolved.
Show resolved Hide resolved
data?: any
}
[key: string]: any
}

Expand Down Expand Up @@ -119,19 +128,19 @@ export function createNuxtApp (options: CreateOptions) {
defineGetter(nuxtApp.vueApp, '$nuxt', nuxtApp)
defineGetter(nuxtApp.vueApp.config.globalProperties, '$nuxt', nuxtApp)

// Expose nuxt to the renderContext
if (nuxtApp.ssrContext) {
nuxtApp.ssrContext.nuxt = nuxtApp
}

if (process.server) {
// Expose nuxt to the renderContext
if (nuxtApp.ssrContext) {
nuxtApp.ssrContext.nuxt = nuxtApp
}
// Expose to server renderer to create window.__NUXT__
nuxtApp.ssrContext = nuxtApp.ssrContext || {} as any
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) {
// Expose client runtime-config to the payload
nuxtApp.payload.config = {
public: options.ssrContext.runtimeConfig.public,
app: options.ssrContext.runtimeConfig.app
Expand Down
7 changes: 4 additions & 3 deletions packages/nuxt/src/core/runtime/nitro/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand All @@ -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
Expand Down
10 changes: 5 additions & 5 deletions packages/nuxt/src/core/runtime/nitro/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down