Here is the simplified code of our Next.js 14 project:
// 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));
}
};
We are trying to get the catch=error into a client-side component’s catch block (try-catch block). What we did in the client component:
// 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;
✅ This is a working code in development
But in Next.js production (npm run build && npm run start
) the throw Error()
is where the entire structure broke.
Next.js Production Build is obscuring all the Error messages:
Error: An error occurred in the Server Components render. The specific
message is omitted in production builds to avoid leaking sensitive
details. A digest property is included on this error instance which
may provide additional details about the nature of the error.
So, instead of having our error object: { foo: "bar" }
, Next.js is returning a String. Hence the JSON.parse()
in the client component is throwing an error instead of parsing our desired error object.
We need to disable the Error suppressing feature of Next.js Production build.
We didn’t find any documentation on Next.js 14 on how to disable the feature:
https://nextjs.org/docs/architecture/nextjs-compiler
Is there a way to do that?