fix(nuxt): improve global/payload error type with NuxtError (#25398)

This commit is contained in:
Damian Głowala 2024-01-28 21:50:53 +01:00 committed by GitHub
parent e01fb7ac3b
commit 9eb0d21ad5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 23 additions and 23 deletions

View File

@ -86,8 +86,10 @@ Customize the default error page by adding `~/error.vue` in the source directory
```vue [error.vue] ```vue [error.vue]
<script setup lang="ts"> <script setup lang="ts">
import type { NuxtError } from '#app'
const props = defineProps({ const props = defineProps({
error: Object error: Object as () => NuxtError
}) })
const handleError = () => clearError({ redirect: '/' }) const handleError = () => clearError({ redirect: '/' })

View File

@ -9,8 +9,10 @@ During the lifespan of your application, some errors may appear unexpectedly at
```vue [error.vue] ```vue [error.vue]
<script setup lang="ts"> <script setup lang="ts">
import type { NuxtError } from '#app'
const props = defineProps({ const props = defineProps({
error: Object error: Object as () => NuxtError
}) })
</script> </script>
@ -31,12 +33,12 @@ The error page has a single prop - `error` which contains an error for you to ha
The `error` object provides the following fields: The `error` object provides the following fields:
```ts ```ts
{ {
url: string
statusCode: number statusCode: number
statusMessage: string fatal: boolean
message: string unhandled: boolean
description: string statusMessage?: string
data: any data?: unknown
cause?: unknown
} }
``` ```

View File

@ -10,6 +10,8 @@ import '#build/fetch.mjs'
import { applyPlugins, createNuxtApp } from './nuxt' import { applyPlugins, createNuxtApp } from './nuxt'
import type { CreateOptions } from './nuxt' import type { CreateOptions } from './nuxt'
import { createError } from './composables/error'
import '#build/css' import '#build/css'
// @ts-expect-error virtual file // @ts-expect-error virtual file
import plugins from '#build/plugins' import plugins from '#build/plugins'
@ -29,9 +31,9 @@ if (import.meta.server) {
try { try {
await applyPlugins(nuxt, plugins) await applyPlugins(nuxt, plugins)
await nuxt.hooks.callHook('app:created', vueApp) await nuxt.hooks.callHook('app:created', vueApp)
} catch (err) { } catch (error) {
await nuxt.hooks.callHook('app:error', err) await nuxt.hooks.callHook('app:error', error)
nuxt.payload.error = (nuxt.payload.error || err) as any nuxt.payload.error = nuxt.payload.error || createError(error as any)
} }
if (ssrContext?._renderResponse) { throw new Error('skipping render') } if (ssrContext?._renderResponse) { throw new Error('skipping render') }
@ -59,9 +61,9 @@ if (import.meta.client) {
const nuxt = createNuxtApp({ vueApp }) const nuxt = createNuxtApp({ vueApp })
async function handleVueError(err: any) { async function handleVueError(error: any) {
await nuxt.callHook('app:error', err) await nuxt.callHook('app:error', error)
nuxt.payload.error = (nuxt.payload.error || err) as any nuxt.payload.error = nuxt.payload.error || createError(error as any)
} }
vueApp.config.errorHandler = handleVueError vueApp.config.errorHandler = handleVueError

View File

@ -84,14 +84,7 @@ export interface NuxtPayload {
state: Record<string, any> state: Record<string, any>
once: Set<string> once: Set<string>
config?: Pick<RuntimeConfig, 'public' | 'app'> config?: Pick<RuntimeConfig, 'public' | 'app'>
error?: Error | { error?: NuxtError | null
url: string
statusCode: number
statusMessage: string
message: string
description: string
data?: any
} | null
_errors: Record<string, NuxtError | null> _errors: Record<string, NuxtError | null>
[key: string]: unknown [key: string]: unknown
} }

View File

@ -5,6 +5,7 @@ import { getRequestHeaders, send, setResponseHeader, setResponseStatus } from 'h
import { useRuntimeConfig } from '#internal/nitro' import { useRuntimeConfig } from '#internal/nitro'
import { useNitroApp } from '#internal/nitro/app' import { useNitroApp } from '#internal/nitro/app'
import { isJsonRequest, normalizeError } from '#internal/nitro/utils' import { isJsonRequest, normalizeError } from '#internal/nitro/utils'
import type { NuxtPayload } from '#app'
export default <NitroErrorHandler> async function errorhandler (error: H3Error, event) { export default <NitroErrorHandler> async function errorhandler (error: H3Error, event) {
// Parse and normalize error // Parse and normalize error
@ -21,7 +22,7 @@ export default <NitroErrorHandler> async function errorhandler (error: H3Error,
: '', : '',
// TODO: check and validate error.data for serialisation into query // TODO: check and validate error.data for serialisation into query
data: error.data as any data: error.data as any
} } satisfies Partial<NuxtPayload['error']> & { url: string }
// Console output // Console output
if (error.unhandled || error.fatal) { if (error.unhandled || error.fatal) {

View File

@ -235,7 +235,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
// Whether we're rendering an error page // Whether we're rendering an error page
const ssrError = event.path.startsWith('/__nuxt_error') const ssrError = event.path.startsWith('/__nuxt_error')
? getQuery(event) as unknown as Exclude<NuxtPayload['error'], Error> ? getQuery(event) as unknown as NuxtPayload['error'] & { url: string }
: null : null
if (ssrError && ssrError.statusCode) { if (ssrError && ssrError.statusCode) {