错误清除
错误发生后,应用需要恢复到正常状态。clearError 用于清除当前错误并恢复应用,useError 用于获取当前全局错误。
clearError
清除当前错误并恢复应用状态:
ts
// 清除错误并跳转到首页
clearError({ redirect: '/' })
// 清除错误不跳转(回到之前的页面状态)
clearError()clearError 的完整行为
- 清除全局错误状态
- 如果传了
redirect,导航到指定页面 - 如果没有
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.vue 中 clearError 的作用
clearError({ redirect: '/' }):清除错误 + 跳转首页clearError():清除错误 + 尝试恢复之前的状态
推荐用 redirect
因为错误页面不在正常路由栈中,不带 redirect 的 clearError 可能导致意外行为。
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:error | Vue 组件渲染错误 | error, instance, info |
app:error | 应用级未捕获错误 | error |
app:chunkError | JS/CSS chunk 加载失败 | { chunkName } |
知识脉络
text
错误页面 → 错误创建与抛出 → 你在这里:错误清除
│
├─→ 下一步:错误边界
│
└─→ 相关:插件与中间件(全局错误处理插件)