错误页面
app/error.vue 是全局错误页面,当应用中发生未捕获的错误时,Nuxt 会显示这个页面。
错误处理机制全景
| 机制 | 作用范围 | 显示方式 | 适用场景 |
|---|---|---|---|
error.vue | 全局 | 全屏错误页面 | 未捕获的错误、404 |
NuxtErrorBoundary | 子组件 | 局部 fallback | 组件级容错 |
try/catch | 代码块 | 自定义处理 | API 调用、表单提交 |
createError | 服务端/客户端 | 抛出错误 | API 路由、中间件 |
showError | 客户端 | 全屏错误页面 | 主动显示错误 |
error.vue 的定位
它是整个应用的"安全网"——当其他错误处理机制都没有捕获到错误时,error.vue 作为最后的兜底。
创建错误页面
vue
<!-- app/error.vue -->
<script setup lang="ts">
const props = defineProps<{
error: {
url: string
statusCode: number
statusMessage: string
message: string
stack: string[]
}
}>()
useHead({
title: `${props.error.statusCode} - 错误`,
})
const is404 = computed(() => props.error.statusCode === 404)
const isDev = import.meta.dev
const handleError = () => clearError({ redirect: '/' })
</script>
<template>
<div class="error-page">
<div class="error-icon">{{ is404 ? '🔍' : '⚠️' }}</div>
<h1>{{ is404 ? '页面未找到' : '出错了' }}</h1>
<p class="error-code">{{ error.statusCode }}</p>
<p class="error-message">
{{ is404 ? '你访问的页面不存在' : error.message || error.statusMessage }}
</p>
<div v-if="isDev && error.stack" class="error-stack">
<pre>{{ error.stack.join('\n') }}</pre>
</div>
<div class="error-actions">
<button @click="handleError" class="btn-home">返回首页</button>
<button @click="$router.back()" class="btn-back">返回上页</button>
</div>
</div>
</template>
<style scoped>
.error-page {
text-align: center;
padding: 4rem 1rem;
min-height: 80vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.error-icon { font-size: 4rem; margin-bottom: 1rem; }
.error-code { font-size: 6rem; font-weight: bold; color: #00DC82; margin: 0.5rem 0; }
.error-message { color: #666; max-width: 400px; }
.error-stack { text-align: left; background: #f5f5f5; padding: 1rem; border-radius: 8px; max-width: 800px; overflow: auto; }
.error-actions { margin-top: 2rem; display: flex; gap: 1rem; }
</style>error 对象属性
| 属性 | 类型 | 说明 | 可用环境 |
|---|---|---|---|
url | string | 请求 URL | 所有环境 |
statusCode | number | HTTP 状态码 | 所有环境 |
statusMessage | string | 状态消息(短描述) | 所有环境 |
message | string | 错误消息(详细描述) | 所有环境 |
stack | string[] | 错误堆栈 | 仅开发模式 |
data | any | 附加数据 | 所有环境 |
statusMessage vs message
statusMessage:简短的 HTTP 状态描述(如"Not Found"、"Forbidden"),会被 HTTP 响应状态行使用,不要放中文或长文本message:详细的错误信息(如"用户不存在"),可包含中文等任意文本,适合传递给前端展示
INFO
️ 生产环境中不要暴露 message 和 stack 可能包含敏感信息
不同错误码的处理
vue
<script setup>
const props = defineProps<{ error: { statusCode: number; statusMessage: string; message: string } }>()
const errorConfig = computed(() => {
switch (props.error.statusCode) {
case 404:
return { icon: '🔍', title: '页面未找到', description: '你访问的页面不存在或已被删除' }
case 403:
return { icon: '🔒', title: '无权访问', description: '你没有权限访问此页面' }
case 401:
return { icon: '🔑', title: '需要登录', description: '请先登录后访问此页面' }
case 500:
return { icon: '💥', title: '服务器错误', description: '服务器出了点问题,请稍后重试' }
default:
return { icon: '⚠️', title: '出错了', description: props.error.message || props.error.statusMessage || '发生了未知错误' }
}
})
</script>常见错误码
- 404:页面不存在(用户访问了不存在的路由)
- 403:无权限(用户没有访问该页面的权限)
- 401:未认证(用户需要登录)
- 500:服务端错误(代码抛出未处理的异常)
注意事项
error.vue不是页面:它不在pages/目录中,不受路由中间件和布局约束- 不能使用某些组合式函数:如
useFetch等依赖路由上下文的函数可能在错误状态下不可用 - 不能使用布局:错误页面不经过
<NuxtLayout>,需要自带完整的 HTML 结构和样式 - 开发模式 vs 生产模式:
error.stack只在开发模式下可用,生产环境中为空数组 - SEO 设置:记得在
error.vue中使用useHead设置错误页面的标题和 meta
知识脉络
text
服务端开发 → 你在这里:错误页面
│
├─→ 下一步:错误创建与抛出
│
└─→ 相关:视图与布局 → 布局(错误页不受布局影响)