
本文详解如何在 Next.js 的 API Routes 中捕获 Laravel 后端返回的业务级错误(如 404、422、500),并通过 NextResponse.json() 统一返回结构化错误响应,使前端能准确显示服务端提示信息。
本文详解如何在 next.js 的 api routes 中捕获 laravel 后端返回的业务级错误(如 404、422、500),并通过 `nextresponse.json()` 统一返回结构化错误响应,使前端能准确显示服务端提示信息。
在 Next.js 应用中,API Routes(如 /api/forgot-password)作为服务端代理层,常用于转发请求至外部后端(如 Laravel)。但一个常见误区是:直接 throw e 或忽略非 2xx 响应,导致前端无法获取业务错误消息(如 "User is not registered."),反而抛出 AxiosError: Request failed with status code 500 等底层网络/状态码错误。
根本原因在于:Axios 默认将 HTTP 状态码 ≥ 400 的响应视为拒绝(rejected promise),即使 Laravel 已返回了包含 message 字段的 JSON 响应体(例如 { success: false, message: "User is not registered." }),Axios 也不会自动解析它——而是将整个响应包装为 AxiosError 并拒绝 Promise。
✅ 正确做法是:在 API Route 中主动捕获 Axios 错误,并显式构造 NextResponse.json() 响应,确保无论后端返回成功(2xx)还是失败(4xx/5xx),API Route 都返回可被前端消费的标准化 JSON:
// app/api/forgot-password/route.ts
import API from "@/lib/axios";
import { NextResponse } from "next/server";
export async function POST(req: Request) {
try {
const { email } = await req.json();
// 注意:此处需配置 axios 实例的 validateStatus,否则 4xx/5xx 会被自动 reject
// 若不修改 axios 配置,必须用 try/catch 捕获所有异常
const res = await API.post("/forgot-password", { email });
// ✅ 成功响应:直接透传 Laravel 的 data 和 status
return NextResponse.json(
{
success: true,
message: res.data.message,
data: res.data,
},
{ status: res.status }
);
} catch (e) {
// ✅ 关键:必须处理错误,不能 throw!
// 先确保 e 是 AxiosError 类型,再安全访问响应数据
if (e?.response?.data) {
return NextResponse.json(
{
success: e.response.data.success ?? false,
message: e.response.data.message ?? "An unexpected error occurred",
error: e.response.data, // 可选:透传完整错误对象供调试
},
{ status: e.response.status || 500 }
);
}
// 降级处理:网络错误或无响应体
return NextResponse.json(
{
success: false,
message: "Network error or server unavailable",
},
{ status: 500 }
);
}
}
⚠️ 重要注意事项:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- 不要 throw e:Next.js API Routes 中 throw 会触发未处理异常,返回默认 500 页面或空响应,前端 useMutation 将收到 AxiosError 而非你期望的业务错误。
- 避免硬编码 res.data 在 catch 块中:原答案中 res.data 在 catch 里是未定义的(res 仅在 try 内有效),已修正为安全访问 e.response.data。
-
推荐增强 axios 配置(可选):若希望 Axios 不自动 reject 4xx 响应,可在 lib/axios.ts 中设置:
const API = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_URL }); API.defaults.validateStatus = (status) => status <p>此时需在 try 内手动判断 res.status >= 400 并统一返回错误响应。</p>
最后,在前端 useMutation 的 onError 回调中即可优雅处理业务错误:
const { mutate, isPending } = useMutation({
mutationFn: (data: FormData) =>
axios.post("/api/forgot-password", data),
onSuccess: () => {
toast({ title: "Success", description: "Email sent!" });
reset();
},
onError: (error: any) => {
// ✅ 现在能拿到 Laravel 的 message
const message = error?.response?.data?.message || "Failed to send email";
toast({
variant: "destructive",
title: "Error",
description: message
});
}
});
通过以上改造,Laravel 返回的 "User is not registered." 将完整透传至前端 UI,实现精准、友好的错误提示。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!








