Next.js 13 App Router中自定义Error页面为何无法处理Fetch API错误?
解决Next.js App Router自定义error.tsx无法捕获API路由Fetch错误的问题
问题原因
你的error.tsx负责捕获所在目录(app/[lang]/)及其子目录下组件渲染时的错误,但src/api/categories/index.ts是独立的服务端API路由,它的错误不会直接触发页面的error.tsx:
- API路由的未处理错误会直接返回Next.js默认错误响应,而非传递给页面组件
- 页面组件调用API时,若未主动处理错误并抛出,
error.tsx无法感知到错误
解决方案步骤
1. 先处理API路由的错误,返回规范响应
在src/api/categories/index.ts中,用try/catch包裹Fetch调用,主动返回带错误状态码的JSON响应,避免未处理错误导致默认错误页:
export async function GET() { try { const res = await fetch("你的外部API地址"); if (!res.ok) { throw new Error(`外部API请求失败: ${res.status}`); } const data = await res.json(); return Response.json(data); } catch (error) { // 返回标准错误响应,而非让错误向上抛出 return Response.json( { message: "获取分类数据失败" }, { status: error instanceof Error ? 500 : 400 } ); } }
2. 在页面组件中主动捕获API响应错误并抛出
以app/[lang]/page.tsx(服务端组件)为例,调用API后检查响应状态,手动抛出错误,让同级的error.tsx捕获:
export async function generateStaticParams() { // 生成静态路由参数,根据你的业务调整 return [{ lang: "en" }, { lang: "zh-CN" }]; } export default async function Page({ params }: { params: { lang: string } }) { try { const res = await fetch(`/api/categories`, { next: { revalidate: 86400 } // SSG缓存配置 }); // 检查API响应状态,主动抛出错误 if (!res.ok) { const errorData = await res.json(); throw new Error(errorData.message || `请求失败: ${res.status}`); } const categories = await res.json(); return <div>{/* 渲染分类内容 */}</div>; } catch (error) { // 重新抛出错误,确保错误冒泡到error.tsx throw error; } }
3. 客户端组件调用API的错误处理(若适用)
如果是客户端组件调用API,需在组件内捕获错误后主动抛出:
"use client"; import { useEffect, useState } from "react"; export default function CategoriesClient() { const [categories, setCategories] = useState<any[]>([]); const [error, setError] = useState<Error | null>(null); useEffect(() => { const fetchData = async () => { try { const res = await fetch("/api/categories"); if (!res.ok) throw new Error(`请求失败: ${res.status}`); const data = await res.json(); setCategories(data); } catch (err) { setError(err as Error); } }; fetchData(); }, []); // 抛出错误,让error.tsx捕获 if (error) throw error; return <div>{/* 渲染分类内容 */}</div>; }
关键注意事项
- 不要将
error.tsx放到src/api/目录下,API路由的错误处理是在内部返回响应,页面错误由app/目录下的error.tsx负责 error.tsx仅捕获组件渲染阶段的错误,必须确保错误在页面/组件层级被抛出,才能触发自定义错误页
内容的提问来源于stack exchange,提问作者EshgheCode
相关产品推荐
相关产品推荐

