mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 13:45:18 +00:00
fix(nuxt3): render nuxt custom error page (#4289)
Co-authored-by: Pooya Parsa <pyapar@gmail.com>
This commit is contained in:
parent
0b12666d49
commit
e43ba6ecd2
@ -44,7 +44,7 @@
|
||||
"magic-string": "^0.26.1",
|
||||
"mlly": "^0.5.1",
|
||||
"murmurhash-es": "^0.1.1",
|
||||
"nitropack": "^0.2.6",
|
||||
"nitropack": "^0.2.7",
|
||||
"node-fetch": "^3.2.3",
|
||||
"nuxi": "3.0.0",
|
||||
"ohash": "^0.1.0",
|
||||
|
@ -69,6 +69,7 @@ export async function setupNitroBridge () {
|
||||
buildDir: resolve(nuxt.options.buildDir),
|
||||
scanDirs: nuxt.options._layers.map(layer => join(layer.config.srcDir, 'server')),
|
||||
renderer: resolve(distDir, 'runtime/nitro/renderer'),
|
||||
errorHandler: resolve(distDir, 'runtime/nitro/error'),
|
||||
nodeModulesDirs: nuxt.options.modulesDir,
|
||||
handlers,
|
||||
devHandlers: [],
|
||||
@ -116,9 +117,6 @@ export async function setupNitroBridge () {
|
||||
'#vue-renderer': resolve(distDir, 'runtime/nitro/vue2'),
|
||||
'#vue2-server-renderer': 'vue-server-renderer/' + (nuxt.options.dev ? 'build.dev.js' : 'build.prod.js'),
|
||||
|
||||
// Error renderer
|
||||
'#nitro/error': resolve(distDir, 'runtime/nitro/error'),
|
||||
|
||||
// Paths
|
||||
'#paths': resolve(distDir, 'runtime/nitro/paths'),
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
||||
"knitwork": "^0.1.1",
|
||||
"magic-string": "^0.26.1",
|
||||
"mlly": "^0.5.1",
|
||||
"nitropack": "^0.2.6",
|
||||
"nitropack": "^0.2.7",
|
||||
"nuxi": "3.0.0",
|
||||
"ohash": "^0.1.0",
|
||||
"ohmyfetch": "^0.4.15",
|
||||
|
@ -25,6 +25,7 @@ export async function initNitro (nuxt: Nuxt) {
|
||||
buildDir: nuxt.options.buildDir,
|
||||
scanDirs: nuxt.options._layers.map(layer => join(layer.config.srcDir, 'server')),
|
||||
renderer: resolve(distDir, 'core/runtime/nitro/renderer'),
|
||||
errorHandler: resolve(distDir, 'core/runtime/nitro/error'),
|
||||
nodeModulesDirs: nuxt.options.modulesDir,
|
||||
handlers,
|
||||
devHandlers: [],
|
||||
@ -77,9 +78,6 @@ export async function initNitro (nuxt: Nuxt) {
|
||||
// Renderer
|
||||
'#vue-renderer': resolve(distDir, 'core/runtime/nitro/vue3'),
|
||||
|
||||
// Error renderer
|
||||
'#nitro/error': resolve(distDir, 'core/runtime/nitro/error'),
|
||||
|
||||
// Paths
|
||||
'#paths': resolve(distDir, 'core/runtime/nitro/paths'),
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
import type { CompatibilityEvent } from 'h3'
|
||||
import { withQuery } from 'ufo'
|
||||
import type { NitroErrorHandler } from 'nitropack'
|
||||
// @ts-ignore TODO
|
||||
import { normalizeError, isJsonRequest } from '#nitro/utils'
|
||||
|
||||
export default async function handleError (error: any, event: CompatibilityEvent) {
|
||||
const { stack, statusCode, statusMessage, message } = normalizeError(error)
|
||||
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 = {
|
||||
url: event.req.url,
|
||||
statusCode,
|
||||
@ -14,24 +17,30 @@ export default async function handleError (error: any, event: CompatibilityEvent
|
||||
? `<pre>${stack.map(i => `<span class="stack${i.internal ? ' internal' : ''}">${i.text}</span>`).join('\n')}</pre>`
|
||||
: ''
|
||||
}
|
||||
event.res.statusCode = error.statusCode || 500
|
||||
event.res.statusMessage = error.statusMessage || 'Internal Server Error'
|
||||
|
||||
// Set response code and message
|
||||
event.res.statusCode = errorObject.statusCode
|
||||
event.res.statusMessage = errorObject.statusMessage
|
||||
|
||||
// Console output
|
||||
if (error.statusCode !== 404) {
|
||||
console.error('[nuxt] [request error]', error.message + '\n' + stack.map(l => ' ' + l.text).join(' \n'))
|
||||
if (errorObject.statusCode !== 404) {
|
||||
console.error('[nuxt] [request error]', errorObject.message + '\n' + stack.map(l => ' ' + l.text).join(' \n'))
|
||||
}
|
||||
|
||||
// JSON response
|
||||
if (isJsonRequest(event)) {
|
||||
event.res.setHeader('Content-Type', 'application/json')
|
||||
return event.res.end(JSON.stringify(errorObject))
|
||||
event.res.end(JSON.stringify(errorObject))
|
||||
return
|
||||
}
|
||||
|
||||
// HTML response
|
||||
const url = withQuery('/__nuxt_error', errorObject as any)
|
||||
const html = await $fetch(url).catch(() => errorObject.statusMessage)
|
||||
const html = await $fetch(url).catch((error) => {
|
||||
console.error('[nitro] Error while generating error response', error)
|
||||
return errorObject.statusMessage
|
||||
})
|
||||
|
||||
event.res.setHeader('Content-Type', 'text/html;charset=UTF-8')
|
||||
return event.res.end(html)
|
||||
event.res.end(html)
|
||||
}
|
||||
|
@ -155,14 +155,13 @@ describe('errors', () => {
|
||||
expect(res.status).toBe(500)
|
||||
const error = await res.json()
|
||||
delete error.stack
|
||||
expect(error).toMatchInlineSnapshot(`
|
||||
{
|
||||
"message": "This is a custom error",
|
||||
"statusCode": 500,
|
||||
"statusMessage": "Internal Server Error",
|
||||
"url": "/error",
|
||||
}
|
||||
`)
|
||||
expect(error).toMatchObject({
|
||||
description: process.env.NUXT_TEST_DEV ? expect.stringContaining('<pre>') : '',
|
||||
message: 'This is a custom error',
|
||||
statusCode: 500,
|
||||
statusMessage: 'Internal Server Error',
|
||||
url: '/error'
|
||||
})
|
||||
})
|
||||
|
||||
it('should render a HTML error page', async () => {
|
||||
|
@ -35,14 +35,13 @@ describe.skip('fixtures:bridge', async () => {
|
||||
expect(res.status).toBe(500)
|
||||
const error = await res.json()
|
||||
delete error.stack
|
||||
expect(error).toMatchInlineSnapshot(`
|
||||
{
|
||||
"message": "This is a custom error",
|
||||
"statusCode": 500,
|
||||
"statusMessage": "Internal Server Error",
|
||||
"url": "/error",
|
||||
}
|
||||
`)
|
||||
expect(error).toMatchObject({
|
||||
description: process.env.NUXT_TEST_DEV ? expect.stringContaining('<pre>') : '',
|
||||
message: 'This is a custom error',
|
||||
statusCode: 500,
|
||||
statusMessage: 'Internal Server Error',
|
||||
url: '/error'
|
||||
})
|
||||
})
|
||||
|
||||
it('should render a HTML error page', async () => {
|
||||
|
14
yarn.lock
14
yarn.lock
@ -2620,7 +2620,7 @@ __metadata:
|
||||
magic-string: ^0.26.1
|
||||
mlly: ^0.5.1
|
||||
murmurhash-es: ^0.1.1
|
||||
nitropack: ^0.2.6
|
||||
nitropack: ^0.2.7
|
||||
node-fetch: ^3.2.3
|
||||
nuxi: 3.0.0
|
||||
nuxt: ^2
|
||||
@ -14547,9 +14547,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nitropack@npm:^0.2.6":
|
||||
version: 0.2.6
|
||||
resolution: "nitropack@npm:0.2.6"
|
||||
"nitropack@npm:^0.2.7":
|
||||
version: 0.2.7
|
||||
resolution: "nitropack@npm:0.2.7"
|
||||
dependencies:
|
||||
"@cloudflare/kv-asset-handler": ^0.2.0
|
||||
"@netlify/functions": ^1.0.0
|
||||
@ -14603,7 +14603,7 @@ __metadata:
|
||||
rollup-plugin-terser: ^7.0.2
|
||||
rollup-plugin-visualizer: ^5.6.0
|
||||
scule: ^0.2.1
|
||||
semver: ^7.3.6
|
||||
semver: ^7.3.7
|
||||
serve-placeholder: ^2.0.1
|
||||
serve-static: ^1.15.0
|
||||
std-env: ^3.0.1
|
||||
@ -14615,7 +14615,7 @@ __metadata:
|
||||
bin:
|
||||
nitro: dist/cli.mjs
|
||||
nitropack: dist/cli.mjs
|
||||
checksum: f932d6f8e648746f9d9b69aa14fe0231a125ffd0a9f8fb3f911d9ed559daa411b9add68a882f6d525c759fd1924edb054e4977628e4727d0160d2849b3503930
|
||||
checksum: 99cf3b20325e3ef27c84ad9d991376fb352bad0bf880741b31534c872067c9d39247b9fe4887c151c3b8e3e0001db6abfdc1be7bde159a1d554c6c4c9747fedd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -15296,7 +15296,7 @@ __metadata:
|
||||
knitwork: ^0.1.1
|
||||
magic-string: ^0.26.1
|
||||
mlly: ^0.5.1
|
||||
nitropack: ^0.2.6
|
||||
nitropack: ^0.2.7
|
||||
nuxi: 3.0.0
|
||||
ohash: ^0.1.0
|
||||
ohmyfetch: ^0.4.15
|
||||
|
Loading…
Reference in New Issue
Block a user