Skip to content

错误页面

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 对象属性

属性类型说明可用环境
urlstring请求 URL所有环境
statusCodenumberHTTP 状态码所有环境
statusMessagestring状态消息(短描述)所有环境
messagestring错误消息(详细描述)所有环境
stackstring[]错误堆栈仅开发模式
dataany附加数据所有环境

statusMessage vs message

  • statusMessage:简短的 HTTP 状态描述(如 "Not Found""Forbidden"),会被 HTTP 响应状态行使用,不要放中文或长文本
  • message:详细的错误信息(如 "用户不存在"),可包含中文等任意文本,适合传递给前端展示

INFO

生产环境中不要暴露 messagestack 可能包含敏感信息

不同错误码的处理

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:服务端错误(代码抛出未处理的异常)

注意事项

  1. error.vue 不是页面:它不在 pages/ 目录中,不受路由中间件和布局约束
  2. 不能使用某些组合式函数:如 useFetch 等依赖路由上下文的函数可能在错误状态下不可用
  3. 不能使用布局:错误页面不经过 <NuxtLayout>,需要自带完整的 HTML 结构和样式
  4. 开发模式 vs 生产模式error.stack 只在开发模式下可用,生产环境中为空数组
  5. SEO 设置:记得在 error.vue 中使用 useHead 设置错误页面的标题和 meta

知识脉络

text
服务端开发 → 你在这里:错误页面

              ├─→ 下一步:错误创建与抛出

              └─→ 相关:视图与布局 → 布局(错误页不受布局影响)

基于 Nuxt 4 官方文档整理编写