---
title: "错误处理"
description: "了解如何在 Nuxt 中捕获和处理错误。"
canonical_url: "https://nuxt.zhcndoc.com/docs/3.x/getting-started/error-handling"
---
# 错误处理

> 了解如何在 Nuxt 中捕获和处理错误。

Nuxt 是一个全栈框架，这意味着在不同环境中可能会发生多种不可避免的用户运行时错误：

- Vue 渲染生命周期中的错误（SSR 和 CSR）
- 服务器和客户端启动错误（SSR + CSR）
- Nitro 服务器生命周期中的错误（[`server/`](https://nuxt.zhcndoc.com/docs/3.x/directory-structure/server) 目录）
- 下载 JS 分块时发生的错误

::tip
**SSR** 代表 **服务器端渲染**，**CSR** 代表 **客户端渲染**。
::

## Vue 错误

你可以使用 [`onErrorCaptured`](https://vuejs.org/api/composition-api-lifecycle#onerrorcaptured) 钩子捕获 Vue 错误。

此外，如果有任何错误向上传播到顶层，Nuxt 会调用 [`vue:error`](https://nuxt.zhcndoc.com/docs/3.x/api/advanced/hooks#app-hooks-runtime) 钩子。

如果你使用错误报告框架，可以通过 [`vueApp.config.errorHandler`](https://vuejs.org/api/application#app-config-errorhandler) 提供全局处理函数。它会接收所有 Vue 错误，即使这些错误已被处理。

```ts twoslash [plugins/error-handler.ts]
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.config.errorHandler = (error, instance, info) => {
    // 处理错误，例如发送报告到服务
  }

  // 也可以这样做
  nuxtApp.hook('vue:error', (error, instance, info) => {
    // 处理错误，例如发送报告到服务
  })
})
```

::note
注意，`vue:error` 钩子是基于 [`onErrorCaptured`](https://vuejs.org/api/composition-api-lifecycle#onerrorcaptured) 生命周期钩子的。
::

## 启动错误

如果在启动 Nuxt 应用时出现任何错误，Nuxt 会调用 `app:error` 钩子。

这包括：

- 运行 [Nuxt 插件](https://nuxt.zhcndoc.com/docs/3.x/directory-structure/plugins)
- 处理 `app:created` 和 `app:beforeMount` 钩子
- 将 Vue 应用渲染为 HTML（在 SSR 期间）
- 挂载应用（在客户端），不过你应该使用 `onErrorCaptured` 或 `vue:error` 处理此情况
- 处理 `app:mounted` 钩子

## Nitro 服务器错误

目前，你无法为这些错误定义服务器端处理程序，但可以渲染错误页面，参见[渲染错误页面](https://nuxt.zhcndoc.com/docs/3.x/getting-started/error-handling#error-page)部分。

## JS 分块错误

你可能会遇到分块加载错误，原因可能是网络连接中断或新部署导致旧的带哈希的 JS 分块 URL 无效。Nuxt 内置支持处理分块加载错误，在路由导航时分块加载失败会执行强制刷新。

你可以通过设置 `experimental.emitRouteChunkError` 为 `false` 来禁用这类错误钩子，或设置为 `manual` 以自行处理它们。如果你想手动处理分块加载错误，可以查看[自动实现](https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/plugins/chunk-reload.client.ts)来获取灵感。

## 错误页面

::note
当 Nuxt 遇到致命错误（服务器端的任何未处理错误，或者客户端通过 `fatal: true` 创建的错误）时，会返回 JSON 响应（如果请求头含 `Accept: application/json`）或者触发全屏错误页面。
::

错误可能在服务器生命周期中发生于：

- 处理你的 Nuxt 插件
- 将 Vue 应用渲染为 HTML
- 服务器 API 路由抛出错误

客户端也可能发生错误，当：

- 处理你的 Nuxt 插件
- 在挂载应用前（`app:beforeMount` 钩子）
- 挂载应用时，如果错误没有通过 `onErrorCaptured` 或 `vue:error` 钩子处理
- Vue 应用在浏览器中初始化并挂载（`app:mounted`）

::read-more{to="https://nuxt.zhcndoc.com/docs/3.x/api/advanced/hooks"}
了解所有 Nuxt 生命周期钩子。
::

通过在应用源目录中添加 `~/error.vue`（与 `app.vue` 同级）可以自定义默认错误页面。

<!-- TODO:twoslash: Twoslash 目前还不支持 tsconfig 路径 -->

```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?.status }}</h2>
    <button @click="handleError">
      Clear errors
    </button>
  </div>
</template>
```

::read-more{to="https://nuxt.zhcndoc.com/docs/3.x/directory-structure/error"}
详细了解 `error.vue` 及其用途。
::

对于自定义错误，我们强烈推荐使用可以在页面/组件 `setup` 函数中调用的 `onErrorCaptured` 组合函数，或者配置在 Nuxt 插件中的 `vue:error` 运行时钩子。

```ts twoslash [plugins/error-handler.ts]
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('vue:error', (err) => {
    //
  })
})
```

当你准备移除错误页面时，可以调用 [`clearError`](https://nuxt.zhcndoc.com/docs/3.x/api/utils/clear-error) 辅助函数；它接受一个可选的重定向路径（例如，如果你想跳转到一个“安全”页面）。

::important
确保在使用任何依赖于 Nuxt 插件的内容前，如 `$route` 或 `useRouter`，先检查是否存在错误；如果有插件抛出错误，它们不会被重新执行，直到错误被清除。
::

::note
渲染错误页面相当于一次完全独立的页面加载，这意味着所有已注册的中间件都会再次运行。你可以在中间件中使用 [`useError`](https://nuxt.zhcndoc.com/docs/3.x/getting-started/error-handling#useerror) 检查是否正在处理错误。
::

::note
如果你使用的是 Node 16，并且在渲染错误页面时设置了任何 cookie，它们会[覆盖之前设置的 cookie](https://github.com/nuxt/nuxt/pull/20585)。建议使用新版 Node，因为 Node 16 于 2023 年 9 月停止维护。
::

## 错误工具

### `useError`

```ts [TS Signature]
function useError (): Ref<Error | { url, status, statusText, message, description, data }>
```

此函数返回当前被处理的全局 Nuxt 错误。

::read-more{to="https://nuxt.zhcndoc.com/docs/3.x/api/composables/use-error"}
详细了解 `useError` 组合式函数。
::

### `createError`

```ts [TS Signature]
function createError (err: string | { cause, data, message, name, stack, status, statusText, fatal }): Error
```

创建一个带有附加元数据的错误对象。你可以传入字符串作为错误的 `message`，或者传入包含错误属性的对象。此函数适用于应用的 Vue 部分和服务器部分，通常用于抛出错误。

如果你抛出使用 `createError` 创建的错误：

- 在服务器端，它会触发全屏错误页面，你可以使用 [`clearError`](https://nuxt.zhcndoc.com/docs/3.x/getting-started/error-handling#clearerror) 清除该页面。
- 在客户端，它会抛出一个非致命错误供你处理。如果你需要触发全屏错误页面，可以将 `fatal: true` 设为真。

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

if (!data.value) {
  throw createError({
    status: 404,
    statusText: 'Page Not Found',
  })
}
</script>
```

::tip
`statusText` 属性用于简短的、符合 HTTP 标准的状态文本（例如 "Not Found"）。它应只包含水平制表符、空格和可见的 ASCII 字符 (`[\t\u0020-\u007E]`)。

对于任何详细描述、多行消息或含非 ASCII 字符的内容，应始终使用 `message` 属性。
::

::read-more{to="https://nuxt.zhcndoc.com/docs/3.x/api/utils/create-error"}
详细了解 `createError` 工具。
::

### `showError`

```ts [TS Signature]
function showError (err: string | Error | { status, statusText }): Error
```

你可以在客户端的任何位置调用此函数，或者（在服务器端）直接在中间件、插件或 `setup()` 函数中调用。它会触发全屏错误页面，你可以使用 [`clearError`](https://nuxt.zhcndoc.com/docs/3.x/getting-started/error-handling#clearerror) 清除该页面。

推荐使用 `throw createError()` 代替。

::read-more{to="https://nuxt.zhcndoc.com/docs/3.x/api/utils/show-error"}
详细了解 `showError` 工具。
::

### `clearError`

```ts [TS Signature]
function clearError (options?: { redirect?: string }): Promise<void>
```

此函数会清除当前处理的 Nuxt 错误。还可以传入一个可选的路径进行重定向（例如，想跳转到一个“安全”页面时）。

::read-more{to="https://nuxt.zhcndoc.com/docs/3.x/api/utils/clear-error"}
详细了解 `clearError` 工具。
::

## 在组件中渲染错误

Nuxt 还提供了 [`<NuxtErrorBoundary>`](https://nuxt.zhcndoc.com/docs/3.x/api/components/nuxt-error-boundary) 组件，让你可以在应用中处理客户端错误，而无需用错误页面替换整个网站。

该组件负责处理其默认插槽中的错误。在客户端，它会阻止错误向上传播到顶层，并渲染 `#error` 插槽。

`#error` 插槽会接收一个 `error` prop。（如果你设置 `error = null`，会触发重新渲染默认插槽；你需要确保错误已完全解决，否则错误插槽会被再次渲染。）

::tip
如果你导航到其它路由，错误会自动清除。
::

```vue [pages/index.vue]
<template>
  <!-- 一些内容 -->
  <NuxtErrorBoundary @error="someErrorLogger">
    <!-- 你用默认插槽渲染内容 -->
    <template #error="{ error, clearError }">
      你可以在这里局部显示错误信息：{{ error }}
      <button @click="clearError">
        这会清除错误。
      </button>
    </template>
  </NuxtErrorBoundary>
</template>
```

::link-example{to="https://nuxt.zhcndoc.com/docs/examples/advanced/error-handling"}
::


## Sitemap

See the full [sitemap](https://nuxt.zhcndoc.com/sitemap.md) for all pages.
