六维教程

Nuxt4 错误处理

网站总会出错,404 页面不存在、500 服务器异常、接口请求失败。好的错误处理让用户看到友好的提示,而不是一片空白或难看的报错页。

全局错误页面

app/error.vue 创建全局错误页面,任何未处理的错误都会渲染到这里:

<!-- app/error.vue -->
<script setup>
// useError 拿到当前错误信息
const error = useError()

function handleBack() {
  clearError({ redirect: '/' })  // 清除错误并跳回首页
}
</script>

<template>
  <div class="error-page">
    <h1>{{ error?.statusCode || '出错了' }}</h1>
    <p>{{ error?.statusMessage || error?.message }}</p>
    <button @click="handleBack">返回首页</button>
  </div>
</template>

访问一个不存在的地址,比如 /nonexistent-page,就会看到这个页面显示 404 错误。

注意error.vue 在 Nuxt 4 中位于 app/error.vue,与 app.vue 平级,它有自己的渲染环境,不经过布局。

主动抛出错误

在接口中抛出

接口层用 createError 抛错,客户端会收到对应状态码:

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

  if (id === '999') {
    throw createError({
      statusCode: 404,
      statusMessage: '用户不存在'
    })
  }

  return { id }
})

在页面中抛出

<!-- app/pages/posts/[id].vue -->
<script setup>
const route = useRoute()

const { data: post } = await useFetch(`/api/posts/${route.params.id}`)

// 数据为空时抛出 404 错误,渲染到全局错误页
if (!post.value) {
  throw createError({
    statusCode: 404,
    statusMessage: '文章不存在'
  })
}
</script>

数据请求失败的处理

接口失败时不一定跳错误页,可以在页面内优雅处理,配合数据获取篇的 error

<script setup>
const { data, error, refresh } = await useFetch('/api/users')
</script>

<template>
  <div v-if="error">
    <p>加载失败:{{ error.statusMessage }}</p>
    <button @click="refresh">重试</button>
  </div>
  <ul v-else>
    <li v-for="user in data" :key="user.id">{{ user.name }}</li>
  </ul>
</template>

提示:请求接口失败默认不会跳转全局错误页(除非设置了 throw: true),页面内的 error 状态更适合局部处理。

组件级错误边界

<NuxtErrorBoundary> 可以捕获组件内部的渲染错误,只影响局部区域,不影响整页:

<template>
  <div>
    <h1>文章列表</h1>
    <NuxtErrorBoundary>
      <PostList />
      <!-- 子组件出错时显示这个插槽 -->
      <template #error="{ error }">
        <p>列表加载失败</p>
        <button @click="error.value = null">重试</button>
      </template>
    </NuxtErrorBoundary>
  </div>
</template>

适合隔离单个功能模块的错误,比如侧边栏挂了不影响主内容区。

错误处理速查表

场景 做法
全局错误页 创建 app/error.vue,用 useError() 读取错误
清除错误跳转 clearError({ redirect: '/' })
接口抛错 throw createError({ statusCode, statusMessage })
页面判断数据缺失 数据为空时 throw createError(...)
请求失败局部提示 useFetcherror 状态配合重试按钮
隔离组件错误 <NuxtErrorBoundary> 包住组件

一句话总结app/error.vue 兜底全局错误,createError 主动抛出可控错误,useFetcherror 处理请求失败,NuxtErrorBoundary 隔离局部错误。

上一篇
Nuxt4 Cookie 与客户端存储
下一篇
Nuxt4 部署上线