如何在TypeScript中正确捕获并展示后端自定义错误?
解决后端自定义错误无法在前端正确展示的问题
问题原因
直接在Next.js后端抛出Error时,框架会返回默认的500状态码响应,并不会将自定义错误信息传递给前端,导致前端只能捕获到通用的"Request failed with status 500"提示。
后端代码修改
需要替换直接抛出错误的逻辑,改为返回包含自定义错误信息的JSON响应,并设置对应的HTTP状态码:
export async function POST(request: Request) { const currentUser = await getCurrentUser(); if (!currentUser) { // 返回401未授权状态+自定义错误信息 return NextResponse.json( { error: "Must be logged in to add reminders!" }, { status: 401 } ); } const body = await request.json(); const user = await prisma.user.findUnique({ where: { email: currentUser.email as string, }, }); const exists = await prisma.reminder.findUnique({ where: { title: body.title, }, }); if (exists) { // 返回409资源冲突状态+自定义错误信息 return NextResponse.json( { error: "Reminder exists, consider changing title!" }, { status: 409 } ); } const reminder = await prisma.reminder.create({ data: { userId: user?.id, ...body, }, }); return NextResponse.json(reminder); }
前端代码修改
Axios的错误对象中,后端返回的自定义错误信息存储在err.response.data里,而非默认的err.message,需要调整捕获逻辑:
基础版本
async function onSubmit(data: ReminderFormSchemaType) { axios .post<ReminderFormSchemaType>("/api/reminders", { ...data }) .then((response) => { toast.success("Reminder added!"); router.refresh(); }) .catch((err) => { // 优先取后端自定义错误,兜底用通用提示 const errorMessage = err.response?.data?.error || "An unexpected error occurred"; toast.error(errorMessage); }); console.log(data); }
带类型定义的严谨版本
如果需要类型约束,可以先定义错误结构:
interface CustomAxiosError { response?: { data?: { error?: string; }; }; message: string; }
然后修改捕获逻辑:
async function onSubmit(data: ReminderFormSchemaType) { axios .post<ReminderFormSchemaType>("/api/reminders", { ...data }) .then((response) => { toast.success("Reminder added!"); router.refresh(); }) .catch((err: CustomAxiosError) => { const errorMessage = err.response?.data?.error || err.message; toast.error(errorMessage); }); console.log(data); }
内容的提问来源于stack exchange,提问作者Mathew
相关产品推荐
相关产品推荐

