这是我们的 Next.js 14 项目的简化代码:
// path/to/action.ts
"use server";
import AuthApi from "@/src/api/auth/auth-api";
export const submitForm = async (payload: any) => {
try {
const response: any = await AuthApi.login(payload);
return {
status: response.data.code,
data: response,
};
} catch (error: any) {
const errorObj = {
status: error.data.code,
data: error,
};
// Triggering an error to get into the catch block.
throw new Error(JSON.stringify(errorObj));
}
};
我们正在尝试将 catch=error 放入客户端组件的 catch 块(try-catch 块)中。我们在客户端组件中做了什么:
// path/to/login.tsx
"use client";
import { submitForm } from "path/to/login/action";
const Login = () => {
try {
// payload here...
const data = await submitForm(payload);
} catch (error) {
console.error(JSON.parse(error.data));
}
return <>Login form</>;
};
export default Login;
✅ 这是开发中的工作代码
但在 Next.js 生产中 (
npm run build && npm run start
),throw Error()
是整个结构崩溃的地方。
Next.js 生产版本掩盖了所有错误消息:
错误:服务器组件渲染中发生错误。具体的 在生产版本中省略消息以避免泄漏敏感信息 细节。此错误实例中包含一个摘要属性,其中 可能会提供有关错误性质的更多详细信息。
因此,Next.js 返回的是一个字符串,而不是我们的错误对象:
{ foo: "bar" }
。因此,客户端组件中的 JSON.parse()
会抛出错误,而不是解析我们想要的错误对象。
我们需要禁用 Next.js 生产版本的错误抑制功能。
我们在 Next.js 14 上没有找到任何有关如何禁用该功能的文档:
https://nextjs.org/docs/architecture/nextjs-compiler
有办法做到吗?
您可以使用
useFormState
和 useFormStatus
挂钩来执行此操作。
查看 Next.js 文档这里。
代替尝试捕获客户端组件上的错误。您需要从服务器组件返回错误。您可以使用
useFormState
在客户端组件上获取它并相应地显示或处理它。
useFormStatus
将有助于显示待处理状态 - 类似于提交表单时的加载程序。