500 Server Error Before Successful MongoDB Connection on Vercel Deployment in Next.js Application

32 Views Asked by At

I built a Next.js app with the App Router and a mongodb database. The page works fine on localhost but the production on Vercel gets a server error with status 500 on initial load because of the API Endpoint /api/prompt/. When I reload the page, everything works fine and the endpoint works and shows the data from the database.

Here is the corresponding code:

/api/prompt:

import { connectToDB } from "@utils/database";
import Prompt from "@models/prompt";

export const dynamic = "force-dynamic";

export const GET = async (request: any) => {
  try {
    await connectToDB();

    const prompts = await Prompt.find({}).populate("creator");

    return new Response(JSON.stringify(prompts), { status: 200 });
  } catch (error) {
    return new Response("Failed to fetch all prompts", { status: 500 });
  }
};

/utils/database:

import mongoose from "mongoose";

let isConnected = false;

export const connectToDB = async () => {
    mongoose.set("strictQuery", true);

    if (isConnected) {
        console.log("MongoDB is already connected");
        return;
    }

    try {
        await mongoose.connect(process.env.MONGODB_URI!, {
            dbName: "share_funfact"
        });

        isConnected = true;

        console.log("MongoDB connected")
    } catch (error) {
        console.log(error);
    }
}

components/feed:

"use client";

const Feed = () => {

 ....

  useEffect(() => {
    const fetchPosts = async () => {
      const response = await fetch("/api/prompt");
      const data = await response.json();

      setPosts(data);
      console.log(data);
    };

    fetchPosts();
  }, []);


  return (
    <section className="feed">
      <form className="relative w-full flex-center">
        <input
          type="text"
          placeholder="Search for a tag or a username"
          value={searchText}
          onChange={handleSearchChange}
          required
          className="search_input peer"
        />
      </form>
      {searchText ? (
        <PromptCardList
          data={searchedResults}
          handleTagClick={handleTagClick}
        />
      ) : (
        <PromptCardList data={posts} handleTagClick={handleTagClick} />
      )}
    </section>
  );
};

I think that the error occurs because the database isn't connected yet but still the server tries to find a connection. You can also find the whole repo on my Github.

Thank you in advance!

1

There are 1 best solutions below

0
MaxPower On

This may have nothing to do with it, but I saw this in some example code.

declare global {
  var mongoose: any; // This must be a `var` and not a `let / const`
}

and also this:

const nextConfig = {
  experimental: {
    esmExternals: 'loose', // <-- add this
    serverComponentsExternalPackages: ['mongoose'], // <-- and this
  },

Also, try just calling dbConnect and your mongo model direct, ie dont go through your own local API but call it with a server component and pass the json into your client component.

I am having problems with vercel and mongoose/mongo. Using app folder setup, going to go back to server side props, really am sick of server side components, every time I use them for something different new problems arise.