Skip to content

错误清除

错误发生后,应用需要恢复到正常状态。clearError 用于清除当前错误并恢复应用,useError 用于获取当前全局错误。

clearError

清除当前错误并恢复应用状态:

ts
// 清除错误并跳转到首页
clearError({ redirect: '/' })

// 清除错误不跳转(回到之前的页面状态)
clearError()

clearError 的完整行为

  1. 清除全局错误状态
  2. 如果传了 redirect,导航到指定页面
  3. 如果没有 redirect,重新渲染之前的页面

INFO

clearError 不带 redirect Nuxt 会尝试重新渲染导致错误的页面。如果错误没有修复,可能会再次触发错误。推荐总是带上 redirect

在 error.vue 中使用

vue
<!-- app/error.vue -->
<script setup lang="ts">
const props = defineProps<{
  error: { statusCode: number; statusMessage: string }
}>()

function goHome() {
  clearError({ redirect: '/' })
}

function goBack() {
  clearError({ redirect: '/' })  // 推荐跳转到安全页面
}
</script>

<template>
  <div>
    <h1>{{ error.statusCode }}</h1>
    <p>{{ error.message }}</p>
    <button @click="goHome">返回首页</button>
  </div>
</template>

error.vueclearError 的作用

  • clearError({ redirect: '/' }):清除错误 + 跳转首页
  • clearError():清除错误 + 尝试恢复之前的状态

推荐用 redirect

因为错误页面不在正常路由栈中,不带 redirectclearError 可能导致意外行为。

useError

获取当前全局错误的引用:

ts
const error = useError()

if (error.value) {
  console.log(error.value.statusCode)
  console.log(error.value.statusMessage)
}

useError 的使用场景

  • 在组件中检查是否有全局错误
  • 根据错误类型显示不同的 UI
  • 在布局中处理全局错误(而非跳转到 error.vue

在布局中处理错误

vue
<!-- app/layouts/default.vue -->
<template>
  <div>
    <header>导航栏</header>

    <!-- 全局错误检查 -->
    <div v-if="error" class="error-banner">
      <p>发生了错误:{{ error.message }}</p>
      <button @click="clearError({ redirect: '/' })">重试</button>
    </div>

    <!-- 正常内容 -->
    <slot v-else />
  </div>
</template>

<script setup>
const error = useError()
</script>

错误恢复流程

text
1. 发生错误

2. Nuxt 显示 error.vue

3. 用户点击"返回首页"

4. clearError({ redirect: '/' })

5. 全局错误状态被清除

6. 导航到首页

7. 页面恢复正常

在 API 中处理错误

服务端错误处理

ts
// server/api/users/[id].ts
export default defineEventHandler((event) => {
  try {
    const id = getRouterParam(event, 'id')
    const user = findUser(id)

    if (!user) {
      throw createError({
        statusCode: 404,
        statusMessage: 'Not Found',
        message: '用户不存在',
      })
    }

    return user
  } catch (error) {
    // 如果是 H3Error(我们主动抛出的),直接传递
    if (isH3Error(error)) {
      throw error
    }

    // 未知错误,包装为 500
    console.error('Unexpected error:', error)
    throw createError({
      statusCode: 500,
      statusMessage: 'Internal Server Error',
      message: '服务器内部错误',
    })
  }
})

isH3Error 的作用

区分"我们主动抛出的业务错误"和"意外的系统错误"。业务错误直接传递,系统错误包装为 500。

客户端错误处理——封装 useApi

ts
// app/composables/useApi.ts
export const useApi = () => {
  const config = useRuntimeConfig()

  async function request<T>(url: string, options?: Record<string, any>): Promise<T> {
    try {
      return await $fetch<T>(url, {
        baseURL: config.public.apiBase,
        ...options,
      })
    } catch (error) {
      if (error instanceof FetchError) {
        // 401 → 跳转登录
        if (error.statusCode === 401) {
          navigateTo('/login')
          throw error
        }

        // 403/404 → 显示错误页面
        if (error.statusCode === 403 || error.statusCode === 404) {
          showError({
            statusCode: error.statusCode,
            statusMessage: error.statusMessage,
            message: error.message,
          })
          throw error
        }
      }

      // 其他错误
      throw createError({
        statusCode: 500,
        statusMessage: 'Network Error',
        message: '网络错误',
      })
    }
  }

  return { request }
}

全局错误处理

通过插件注册全局错误钩子,统一处理未捕获的错误:

ts
// app/plugins/error-handler.ts
export default defineNuxtPlugin((nuxtApp) => {
  // Vue 组件渲染错误
  nuxtApp.hook('vue:error', (error, instance, info) => {
    console.error('Vue 渲染错误:', error)
    // 上报到 Sentry / 其他监控
  })

  // 应用级错误
  nuxtApp.hook('app:error', (error) => {
    console.error('应用错误:', error)
  })

  // 请求错误
  nuxtApp.hook('app:chunkError', (error) => {
    console.error('资源加载错误:', error)
    // 可以提示用户刷新页面
  })
})

Nuxt 错误钩子

钩子触发时机参数
vue:errorVue 组件渲染错误error, instance, info
app:error应用级未捕获错误error
app:chunkErrorJS/CSS chunk 加载失败{ chunkName }

知识脉络

text
错误页面 → 错误创建与抛出 → 你在这里:错误清除

                               ├─→ 下一步:错误边界

                               └─→ 相关:插件与中间件(全局错误处理插件)

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