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?
2
Answers
You can use
useFormState
anduseFormStatus
hooks to do so.Check out Next.js documentation here.
In place of trying to catch an error on client component. You need to return your error from the server component. You can get this on client component using
useFormState
and display it or handle it accordingly.useFormStatus
will be useful to show the pending state – something like loader while the form is being submitted.You can Use try,catch on the Client Side
bind your web api calls on a try/catch to handle the server response appropriately