Next.js error in production mode - Digest: 1782794309
Asked Answered
M

5

12

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?

Marche answered 22/5, 2023 at 11:24 Comment(3)
Following the advice on the screen, what does the console say?Lenard
Try replicating the error in a development environment for more details, when you have done that; Update your post with the console output.Lenard
@Marche I am the same. did you solve it?Prohibitionist
A
8

I ran into this issue and the problem was my use of generateStaticParams. Locally all of my code worked, it built locally and on Vercel but when I visited some routes on Vercel, this error presented itself:

[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.] { digest: 'DYNAMIC_SERVER_USAGE', page: '/xyz' }

This is a key piece of information just sort of casually mentioned in the 'Good to Know' part of the docs:

During next build, generateStaticParams runs before the corresponding Layouts or Pages are generated.

You have to double check how you are rendering things in your application. We're using a mix of static and SSR which is why I got mixed up.

What happened was I used generateStaticParams on a path that was SSR, so the build worked because it could access the data but then the pages never got created because it's SSR. So when the client goes to the path, there's no static page to render - so you get the 500 error.

Easy fix - just get rid of generateStaticParams on any SSR route and you should be good.

  • Next v14.1.0 and Node v18.x

Edit: read Ben S' comment below. It is the use of the certain client-side functions that actually caused the 500 error. In my case it was searchParams.

Adultery answered 22/1 at 13:56 Comment(8)
Thanks @Adultery ! I was using generateStaticParams on an SSR route which doesn't make sense. After removing generateStaticParams the error disappeared.Coccidiosis
I've upvoted your response, but the reasons are not quite accurate. This error occurs due to the use of dynamic functions inside the page. Such as cookies or use of urlParams. The build will succeed, as you stated. This means, your pages are built anticipating static rendering but at runtime, they are using dynamic things on the server => DYNAMIC_SERVER_USAGEStipulation
Interesting @BenS - I was using searchParams on that route which has to be looking at something rendered. But what do you mean 'anticipating static rendering'? I thought Next figured out the correct type of strategy when you opt into app router, no?Adultery
By 'anticipating static rendering' I mean: because of using generateStaticParams NextJS expects the relevant paths are statically generated, and upon visit it realizes that there are dynamic functions in use, but this does not get flagged by the build tool as the paths are generated before the pages are built. Hella confusing as everything is in 1 file.Stipulation
Ah, that makes sense. It felt like something the build should catch.Adultery
Yeah, totally confusing. Start adding in interleaving and you've got a recipe for a headache 😀 tho this thread does shed some light on a few things. twitter.com/delba_oliveira/status/1767958810356756798Stipulation
If deep prop drilling is the preferred pattern, it really takes the shine off server components.Adultery
generateStaticParams ONLY works in a root page.tsx file. It runs at build time and is the apparatus by which SSG is possible with the app router.Sundries
J
2

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.

Juetta answered 24/7 at 5:51 Comment(0)
D
1

what solution was i found is add env NEXTAUTH_URL on vercel and then redeploying the app. NEXTAUTH_URL should be the URL of your project, such as https://example.com.

NEXTAUTH_URL="https://example.com"

Sorry for my bad English.

Dvandva answered 12/4 at 9:52 Comment(0)
R
0

I'm not sure if it's the most optimal solution, but in my case, I found that the problem was trying to directly fetch in a server component. In my case, I converted my component to a client component using 'use client' but I changed the way of doing the fetch as follows:

create a function outside in a services file looks like this:

import axios from "axios";
const API_URL = '/api/item/';

const handleViewDetails = async (itemId: string) => {
    try {
      const response = await axios.get(`${API_URL}${itemId}`);
      return response.data;
    } catch (error:any) {
  
      const errorMessage = error.response?.data?.message || "Could not fetch item.";
      console.error('Error fetching item:', errorMessage);
      throw new Error(errorMessage);
    }
  };

  export default handleViewDetails;

my component looks like:

  "use client"
  import { useEffect, useState } from "react";
  import handleViewDetails from "./services";
  import { useParams } from "next/navigation";

  const DetailPage: React.FC = () => {
  const { id } = useParams<{ id: string }>();
  const [loading, setLoading] = useState<boolean>(false);


  const [itemData, setItemData] = useState<ItemType | null>(null);

  useEffect(() => {
    setLoading(true);
    handleViewDetails(id)
      .then((data: item) => { 
        setItemData(data);
        setLoading(false);
      })
      .catch((error: Error) => {
        console.error("Failed to load item:", error);
        setLoading(false);
      });
  }, [id]); 

  if (loading) {
    return <h1>Loading...</h1>;
  }

  if (!item) {
    return <h1>No tourist data found.</h1>;
  }

  return (
    <>
      <h1>{itemData.data}</h1>
      <h1>{itemData.data}</h1>
      <h1>{itemData.data}</h1>
    </>
  );
};

export default DetailPage;

In my case, the error occurred when fetching the details of an item, which is why I'm providing this example

Rochette answered 7/11, 2023 at 1:58 Comment(0)
G
0

In my case it was the environment variables. I was missing the environment variable in the build pipeline. Adding it fixed my error.

Giralda answered 13/5 at 10:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.