Nuxt:如何获取服务端错误页异常信息?全局处理服务端错误方案
在Nuxt中处理服务端错误的实现方案
一、服务端错误页面获取异常信息
在Nuxt 2及以上版本中,默认的错误页面(layouts/error.vue)会通过props.error接收服务端抛出的错误对象,可直接从中提取信息:
<template> <div class="error-container"> <h1>500 - 服务器错误</h1> <p>{{ error?.message || '未知错误' }}</p> <!-- 开发环境展示堆栈信息 --> <pre v-if="process.env.NODE_ENV !== 'production'">{{ error?.stack }}</pre> </div> </template> <script> export default { props: ['error'] } </script>
如果是纯服务端中间件(如serverMiddleware)抛出的错误,需要通过自定义中间件捕获后传递信息,或直接在中间件中返回错误内容。
二、全局捕获服务端错误并实现条件重定向
完全可以实现你想要的「生产环境重定向到自定义页面,开发环境展示堆栈」需求,分版本说明实现方式:
Nuxt 2 实现方式
1. 自定义服务端中间件捕获全局错误
创建server-middleware/global-error-handler.js:
module.exports = (req, res, next) => { // 捕获后续中间件抛出的同步错误 try { next() } catch (err) { handleServerError(err, req, res) } // 捕获异步错误 res.on('error', (err) => handleServerError(err, req, res)) } function handleServerError(err, req, res) { if (process.env.NODE_ENV === 'production') { // 重定向到自定义错误页面,编码错误信息避免乱码 const encodedMsg = encodeURIComponent(err.message || '服务器内部错误') res.writeHead(302, { Location: `/error?message=${encodedMsg}` }) res.end() } else { // 返回带堆栈的原始错误页面 res.writeHead(500, { 'Content-Type': 'text/html' }) res.end(` <h2>服务端错误</h2> <p>${err.message}</p> <pre style="white-space: pre-wrap;">${err.stack}</pre> `) } }
在nuxt.config.js中注册这个中间件:
export default { serverMiddleware: [ '~/server-middleware/global-error-handler.js' ] }
2. 通过Nuxt错误钩子处理渲染过程中的错误
如果要捕获页面asyncData/fetch方法抛出的服务端错误,创建插件plugins/error-handler.js:
export default function ({ app, error: nuxtError }) { // 覆盖Nuxt内置的error方法 app.context.error = (err) => { if (process.env.NODE_ENV === 'production') { app.context.redirect(302, `/error?message=${encodeURIComponent(err.message || '服务器错误')}`) } else { // 调用默认错误处理,展示堆栈信息 nuxtError(err) } } }
在nuxt.config.js中注册插件:
export default { plugins: [ '~/plugins/error-handler.js' ] }
Nuxt 3 实现方式
Nuxt 3基于Nitro引擎,处理方式如下:
1. Nitro中间件捕获全局服务端错误
创建server/middleware/global-error-handler.js:
export default defineEventHandler((event) => { // 捕获异步错误 event.node.res.on('error', (err) => handleError(err, event)) // 拦截响应,判断是否为5xx错误 const originalSend = event.node.res.send event.node.res.send = function (data) { if (event.node.res.statusCode >= 500) { const err = new Error(typeof data === 'string' ? data : '服务器内部错误') handleError(err, event) } return originalSend.call(this, data) } }) function handleError(err, event) { if (process.env.NODE_ENV === 'production') { const encodedMsg = encodeURIComponent(err.message || '服务器错误') return sendRedirect(event, `/error?message=${encodedMsg}`, 302) } else { // 返回默认带堆栈的错误响应 return sendError(event, err) } }
2. 通过app:error钩子处理应用级错误
创建plugins/error-handler.js:
export default defineNuxtPlugin((nuxtApp) => { nuxtApp.hook('app:error', (err) => { if (process.env.NODE_ENV === 'production') { const encodedMsg = encodeURIComponent(err.message || '服务器错误') navigateTo(`/error?message=${encodedMsg}`) } else { // 开发环境打印错误堆栈 console.error('服务端错误:', err) } }) })
三、关于app/views/error.html无效的问题
app/views/error.html是Nuxt 1.x的旧用法,在Nuxt 2及以上版本已被废弃。当前版本中,自定义错误页面需要使用pages/error.vue(路由级错误页面)或layouts/error.vue(全局错误布局)。
自定义错误页面示例
创建pages/error.vue作为生产环境的错误页面:
<template> <div class="custom-error-page"> <h1>😵 出错了</h1> <p>{{ errorMessage }}</p> </div> </template> <script setup> const route = useRoute() const errorMessage = route.query.message || '服务器发生未知错误' </script>
内容的提问来源于stack exchange,提问作者d-_-b
相关产品推荐
相关产品推荐

