You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生产环境NextJS+Mongoose连接数据库时出现504/500错误求助

NextJS + Mongoose 生产环境注册接口500/504错误排查

问题描述

跟着YouTube上的项目搭建了NextJS+Mongoose的认证流程,试过React Server Actions和API调用两种实现方式,本地环境运行完全正常,但部署到Vercel、Heroku生产环境后,注册接口调用时持续出现504或500错误。已配置数据库环境变量,但生产环境始终无法正常运行,求排查原因。

相关代码

注册页面组件

"use client";
import Link from "next/link";
import React, { useEffect } from "react";
import {useRouter} from "next/navigation";
import axios from "axios";
import { toast } from "react-hot-toast";


export default function SignupPage() {

    const router = useRouter();
    
    const [user, setUser] = React.useState({
        email: "",
        password: "",
        username: "",
    })
    const [buttonDisabled, setButtonDisabled] = React.useState(false);
    const [loading, setLoading] = React.useState(false);

    const onSignup = async () => {
        try {
            setLoading(true);
            const response = await axios.post("/api/users/signup", user);
            console.log("Signup success", response.data);
            router.push("/login");
            
        } catch (error:any) {
            console.log("Signup failed", error.message);
            
            toast.error(error.message);
        }finally {
            setLoading(false);
        }
    }

    useEffect(() => {
        if(user.email.length > 0 && user.password.length > 0 && user.username.length > 0) {
            setButtonDisabled(false);
        } else {
            setButtonDisabled(true);
        }
    }, [user]);


    return (
    <div className="flex flex-col items-center justify-center min-h-screen py-2">
        <h1>{loading ? "Processing" : "Signup"}</h1>
        <hr />
        <label htmlFor="username">username</label>
        <input 
        className="p-2 border border-gray-300 rounded-lg mb-4 focus:outline-none focus:border-gray-600 text-black"
            id="username"
            type="text"
            value={user.username}
            onChange={(e) => setUser({...user, username: e.target.value})}
            placeholder="username"
            />
        <label htmlFor="email">email</label>
        <input 
        className="p-2 border border-gray-300 rounded-lg mb-4 focus:outline-none focus:border-gray-600 text-black"
            id="email"
            type="text"
            value={user.email}
            onChange={(e) => setUser({...user, email: e.target.value})}
            placeholder="email"
            />
        <label htmlFor="password">password</label>
        <input 
        className="p-2 border border-gray-300 rounded-lg mb-4 focus:outline-none focus:border-gray-600 text-black"
            id="password"
            type="password"
            value={user.password}
            onChange={(e) => setUser({...user, password: e.target.value})}
            placeholder="password"
            />
            <button
            onClick={onSignup}
            className="p-2 border border-gray-300 rounded-lg mb-4 focus:outline-none focus:border-gray-600">{buttonDisabled ? "No signup" : "Signup"}</button>
            <Link href="/login">Visit login page</Link>
        </div>
    )

}

API路由代码

import {connect} from "@/dbConfig/dbConfig";
import User from "@/models/userModel";
import { NextRequest, NextResponse } from "next/server";
import bcryptjs from "bcryptjs";


connect()


export async function POST(request: NextRequest){
    try {
        const reqBody = await request.json()
        const {username, email, password} = reqBody

        console.log(reqBody);

        //check if user already exists
        const user = await User.findOne({email})

        if(user){
            return NextResponse.json({error: "User already exists"}, {status: 400})
        }

        //hash password
        const salt = await bcryptjs.genSalt(10)
        const hashedPassword = await bcryptjs.hash(password, salt)

        const newUser = new User({
            username,
            email,
            password: hashedPassword
        })

        const savedUser = await newUser.save()
        console.log(savedUser);

        //send verification email
        return NextResponse.json({message: "success"}, {status: 200})

    } catch (error: any) {
        return NextResponse.json({error: error.message}, {status: 500})

    }
}

数据库连接代码

import mongoose from 'mongoose';

export async function connect() {
    try {
        mongoose.connect(process.env.MONGO_URI!);
        const connection = mongoose.connection;

        connection.on('connected', () => {
            console.log('MongoDB connected successfully');
        })

        connection.on('error', (err) => {
            console.log('MongoDB connection error. Please make sure MongoDB is running. ' + err);
            process.exit();
        })

    } catch (error) {
        console.log('Something goes wrong!');
        console.log(error);
        
    }

}

错误日志

frame_ant.js:1 
        
        
       POST https://hate-my-life-2263e32f7a48.herokuapp.com/api/users/signup 500 (Internal Server Error)
t.send @ frame_ant.js:1
(anonymous) @ 124-4ee39ffa73575f2e.js:14
xhr @ 124-4ee39ffa73575f2e.js:14
ex @ 124-4ee39ffa73575f2e.js:14
request @ 124-4ee39ffa73575f2e.js:14
(anonymous) @ 124-4ee39ffa73575f2e.js:14
(anonymous) @ 124-4ee39ffa73575f2e.js:14
m @ page-e1564dbf3d774990.js:1
ae @ bce60fc1-ece4c58e84f01921.js:9
ao @ bce60fc1-ece4c58e84f01921.js:9
(anonymous) @ bce60fc1-ece4c58e84f01921.js:9
u8 @ bce60fc1-ece4c58e84f01921.js:9
u6 @ bce60fc1-ece4c58e84f01921.js:9
(anonymous) @ bce60fc1-ece4c58e84f01921.js:9
oC @ bce60fc1-ece4c58e84f01921.js:9
io @ bce60fc1-ece4c58e84f01921.js:9
sn @ bce60fc1-ece4c58e84f01921.js:9
i9 @ bce60fc1-ece4c58e84f01921.js:9
i5 @ bce60fc1-ece4c58e84f01921.js:9
page-e1564dbf3d774990.js:1 Signup failed Request failed with status code 500

排查关键点

数据库连接问题

  • 检查MongoDB Atlas的IP白名单设置,确认是否允许Vercel/Heroku的服务器IP访问,可临时开放0.0.0.0/0测试(测试后需及时改回)
  • 验证生产环境的MONGO_URI是否正确,避免复制时遗漏后缀、密码错误等问题,可在API路由中添加console.log(process.env.MONGO_URI)打印验证
  • 修改数据库连接代码,添加await等待连接完成:
    // 原代码
    mongoose.connect(process.env.MONGO_URI!);
    // 修改后
    await mongoose.connect(process.env.MONGO_URI!);
    
    同时API路由中需等待连接函数执行:
    // 原代码
    connect()
    // 修改后
    await connect()
    

API路由异步处理问题

  • 确保bcryptjs依赖已正确安装到生产环境,检查package.json中是否包含该依赖,避免生产构建时遗漏
  • 可适当降低bcryptjs的salt值(比如从10改为8),减少密码哈希的计算时间,避免触发平台超时限制

超时与平台限制

  • Heroku免费版有30秒请求超时限制,若数据库操作+哈希计算耗时过长会触发504错误,需优化操作速度
  • 选择MongoDB Atlas的就近节点,降低网络延迟

日志排查

  • 查看Vercel/Heroku的服务器日志,确认API路由中的console.log(reqBody)、console.log(savedUser)是否输出,定位请求是否到达服务器、在哪一步出错
  • 完善catch块的错误日志,打印详细错误信息:
    catch (error: any) {
        console.error("Signup API Error:", error);
        return NextResponse.json({error: error.message}, {status: 500})
    }
    

内容的提问来源于stack exchange,提问作者lyub12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 09:05:55