首页 / Nuxt 4 入门教程 / 错误处理与自定义错误页

Nuxt 4 入门教程

错误处理与自定义错误页

本教程共 50 篇 · 第 41 篇 · 更新于 2026-08-08 · 约 8 分钟阅读

NuxtNuxt4错误处理createErrorerror.vueonErrorCaptured

本节目标:理解 Nuxt 的错误处理体系,能抛出错误、自定义全站错误页,并在局部优雅地捕获组件错误。

41-1

Nuxt 是全栈框架,错误可能出现在好几个地方:Vue 渲染时的报错、应用启动失败、Nitro 服务端报错、甚至浏览器下载 JS 分块(chunk)失败。SSR 和 CSR 都可能出错,所以不能只在前端兜底。

好消息是:Nuxt 把这些情况归并到一套清晰的 API 里,你只要记住几个核心函数就能应对大多数场景。

41-2

createError 用来创建一个带元数据的错误对象,通常配合 throw 使用。它既能在服务端用,也能在客户端用。

<script setup lang="ts">
const route = useRoute()
const { data } = await useFetch(`/api/movies/${route.params.slug}`)

if (!data.value) {
  throw createError({
    statusCode: 404,
    statusMessage: '页面未找到',
  })
}
</script>

createError 接收一个对象,常用字段有:statusCode(HTTP 状态码)、statusMessage(状态文案)、message(错误说明)、fatal(是否致命)。

Note

服务端抛出的 createError 会触发全屏错误页;客户端抛出的默认是「非致命错误」,由你自行处理。想要客户端也触发全屏错误页,把 fatal: true 加上即可。

41-3

Nuxt 默认有个错误页,但大多时候你要换成自己的风格。只要在源码根目录(Nuxt 4 是 app/error.vue,与 app.vue 并列)建一个 error.vue

<script setup lang="ts">
import type { NuxtError } from '#app'

const props = defineProps({
  error: Object as () => NuxtError,
})

const handleError = () => clearError({ redirect: '/' })
</script>

<template>
  <div>
    <h2>{{ error?.statusCode }}</h2>
    <p>{{ error?.message }}</p>
    <button @click="handleError">回到首页</button>
  </div>
</template>

错误页会收到一个 error prop,里面有 statusCodestatusMessagemessage 等信息。点击按钮调用 clearError 即可「消除错误状态」,可选重定向到安全页面。

Warning

渲染错误页是一次「完整的独立页面加载」,意味着所有中间件会再跑一遍。在中间件里可以用 useError() 判断当前是否处于错误态,避免死循环重定向。

41-4

有时候你不想整页崩掉,只想「这块出错就显示个提示」。用 <NuxtErrorBoundary> 包裹内容,错误会被圈在局部:

<template>
  <NuxtErrorBoundary @error="someErrorLogger">
    <SomeRiskyComponent />
    <template #error="{ error, clearError }">
      <p>出错了:{{ error }}</p>
      <button @click="clearError">重试</button>
    </template>
  </NuxtErrorBoundary>
</template>

#error 插槽能拿到 errorclearError,客户端渲染期间它会阻止错误冒泡到顶层,只替换这一块。

也可以用组合式函数 onErrorCaptured 在 setup 里捕获:

onErrorCaptured((err) => {
  console.error('捕获到子组件错误', err)
  // 返回 false 阻止错误继续向上传播
  return false
})

41-5

想在错误发生时统一上报(比如发到 Sentry),在插件里挂监听最合适:

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.config.errorHandler = (error, instance, info) => {
    // 上报到监控服务
    console.error('全局错误', error, info)
  }

  nuxtApp.hook('vue:error', (error) => {
    console.error('vue:error', error)
  })
})

vue:error 基于 onErrorCaptured,能捕获所有冒泡到顶层的 Vue 错误,连已被 onErrorCaptured 处理过的也能收到。

41-6

  • useError():返回当前正在处理的全局错误,是个 ref。
  • showError(err):在客户端任意时刻调用,触发全屏错误页。官方建议优先用 throw createError()
  • clearError({ redirect }):清除当前错误,可选重定向。
Tip

清除错误前,别急着依赖某些插件注入的东西(如 $routeuseRouter)。如果那个插件抛过错,在你 clearError 之前它不会重跑。先确认所需能力可用,再操作。

41-7

Nuxt 3 与 Nuxt 4 的错误处理 API 一致,createError/error.vue/clearError/onErrorCaptured 用法相同。唯一的目录差异是错误页位置:Nuxt 3 在根 error.vue,Nuxt 4 在 app/error.vue

41-8

Nuxt 的错误体系可以分成三层,别混着用:

  • 全屏错误页error.vue + createError):整页崩了用。比如路由参数对应的数据不存在,直接 throw createError({ statusCode: 404 }),用户看到的是你的错误页,不是白屏。
  • 局部边界<NuxtErrorBoundary> / onErrorCaptured):只有某一块出错。比如一个第三方图表组件可能崩,把它包起来,崩了只显示「加载失败」提示,页面其他部分照常工作。
  • 全局上报vue:error / errorHandler,放插件):不阻断用户体验,只负责把错误发到监控后台。
Tip

选哪一层的判断标准:这个错误「该不该让用户离开当前页面」。该离开 → 全屏页;不该离开、只是局部坏 → 边界;都不影响、只是想记录 → 上报。

41-9

error.vue 渲染时不会走你平时的 layouts,它是一张独立的全屏页。所以别指望在错误页里用 useRoute、依赖某个页面级中间件状态——前面提过,渲染错误页时所有中间件会再跑一遍,但布局、页面级 definePageMeta 都不会生效。错误页应该尽量自包含:只展示状态码、信息、一个「返回首页」按钮。

41-10

throw createError 是「主动抛」,常写在 await useFetch 之后判断数据是否为空。onErrorCaptured 是「被动接」,写在某父组件的 setup 里接住子组件冒上来的错。两者配合:页面主动抛 404,全局又用 vue:error 兜住所有漏网的,形成双层保险。 还有一点:createErrorstatusCode 会决定 HTTP 响应状态码(服务端渲染时)和错误页的展示。404、500 这些常见码直接用;自定义业务逻辑错误尽量映射到合适的标准码,方便监控平台聚合统计。客户端用 showError 也能触发全屏页,但官方更推荐 throw createError,因为它能带着上下文一起抛出,定位问题更方便,也更容易在错误页里展示准确信息。

41-11

createError 抛错、app/error.vue 定制全屏错误页、clearError 消除错误;局部用 <NuxtErrorBoundary>onErrorCaptured;全局上报放插件里。下一章我们看怎么让你的网站被搜索引擎和社交平台读懂:SEO 与元信息。

41-7 错误监控与上报

生产环境里的错误不能只靠用户反馈来发现。建立一套错误监控机制,能让你在用户投诉之前就知道问题存在。常见的做法是在 app:error 钩子里把错误信息上报到监控平台,如 Sentry、LogRocket 或自建的服务。

上报时应该包含足够的上下文信息:错误消息、堆栈跟踪、发生时间、用户 ID(脱敏)、当前路由等。这些信息能帮你快速定位问题。但要避免上报敏感数据,如密码、令牌、个人身份信息。

除了运行时错误,还应该关注 HTTP 错误率。如果某个 API 路由的 500 错误突然增多,通常意味着服务端出了问题。Nuxt 的服务端中间件可以记录每个请求的状态码,配合日志系统做统计分析。

41-8 全局错误与局部错误的处理策略

Nuxt 里的错误分两种:全局错误(导致整个页面无法渲染)和局部错误(只影响页面的某个部分)。两种错误需要不同的处理策略。

全局错误由 Nuxt 的错误处理机制统一接管,最终展示 error.vue 里定义的错误页面。你可以在这里提供返回首页的链接、搜索框、或者联系客服的入口,帮助用户走出困境。

局部错误则应该在组件内部处理。用 Vue 的 onErrorCaptured 钩子捕获子组件的错误,显示一个友好的占位内容而不是让整个页面崩溃。比如一个数据加载失败的卡片组件,可以显示”加载失败,点击重试”,而不是让整个页面白屏。