Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Next.js error in production mode - Digest: 1782794309

I use Next 13.4.3. I don't have an API folder in the app folder as described here, by default all pgaes.tsx etc. are in the app folder SSR: https://nextjs.org/docs/app/building-your-application/routing/router-handlers. In my main page /app/page.tsx I do a fetch when called to load data from MongoDB (app/products/route.ts). Everything works locally as soon as I switch to production mode, I get the error below

enter image description here

Application error: a client-side exception has occurred (see the browser console for more information). Digest: 1782794309

And in the Chrome Debuger Console:

139-fafe6b4f143efdb1.js:1 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.

if i click on 139-fafe6b4f143efdb1.js i got this:

enter image description here

How do I find out where the error is?

like image 307
Captai-N Avatar asked Sep 12 '25 17:09

Captai-N


1 Answers

Solution HERE!

I found the solution to handling expected errors in React server actions in this article: https://joulev.dev/blogs/throwing-expected-errors-in-react-server-actions

Issue: When handling server actions, simply using throw new Error() to manage expected errors (like wrong passwords or usernames already taken) isn't effective in production. During development (yarn dev), errors are passed to the frontend as expected, but in production (yarn start), you'll encounter this error message:

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 in this error instance which may provide additional details about the nature of the error.

This happens because Next.js protects against directly throwing errors in server actions in production. Instead, you should return the error.

Original Server Action Code which Fails to send error to frontend in production:

"use server";
export const createDeposit = async (values: CreateDepositSchemaType, token: string) => {
  try {
    return await handleServerPost(`${USERS_API}deposits/create`, values, token);
  } catch (error: any) {
    await handleServerError(error);
    throw new Error(error);
  }
};

export async function handleServerError(error: any) {
  try {
    if (error && error.message === "Unauthorized") await logout();
    if (axios.isAxiosError(error)) {
      const response = error.response;
      if (response?.statusText === "Unauthorized" || response?.data.message === "Unauthorized") await logout();
      if (response && response.data) {
        const { message, statusCode } = response.data;
        // Handle specific status code 409
        if (statusCode !== 200) {
          console.log("Conflict error: ", message);
          throw new Error(message);
        }
        throw new Error(message);
      }
      if (error.code === "ECONNREFUSED") {
        throw new Error("Connection refused. Please try again later or contact support.");
      }
    } else {
      throw new Error("Unknown server error, Please try again later or contact support.");
    }
  } catch (error: any) {
    console.log("CATCHING ERR:", error);
    throw new Error(error);
  }
}

Updated Server Action Code for Production SOLUTION:

"use server";
export const createDeposit = async (values: CreateDepositSchemaType, token: string) => {
  try {
    return await handleServerPost(`${USERS_API}deposits/create`, values, token);
  } catch (error: any) {
    return await handleServerError(error);
  }
};

// ERROR HANDLERS
export async function handleServerError(error: any) {
  try {
    if (error && error.message === "Unauthorized") await logout();
    if (axios.isAxiosError(error)) {
      const response = error.response;
      if (response?.statusText === "Unauthorized" || response?.data.message === "Unauthorized") await logout();
      if (response && response.data) {
        const { message, statusCode } = response.data;
        // Handle specific status code 409
        if (statusCode !== 200) {
          console.log("Conflict error: ", message);
          return { message, statusCode };
        }
        return { message, statusCode };
      }
      if (error.code === "ECONNREFUSED") {
        return { message: "Connection refused. Please try again later or contact support.", statusCode: 500 };
      }
    } else {
      return { message: "Unknown server error, Please try again later or contact support.", statusCode: 500 };
    }
  } catch (catchError: any) {
    return { message: catchError.message, statusCode: 500 };
  }
}

CONCLUSION: This adjustment ensures that errors are returned properly and can be read by the frontend, even in production.

In a few words: Use return on server actions side, not throw if you want to get the error in the frontend.

like image 143
Kenneth Zambrano Avatar answered Sep 15 '25 15:09

Kenneth Zambrano