第二次/第三次请求MongoDB数据时Express服务器崩溃求助
问题排查:Express服务器多次请求后拒绝连接
项目代码
const express = require("express"); const app = express(); const mongoose = require("mongoose"); const Listing = require("./models/listings"); const path = require("path"); const methodOverride = require("method-override"); app.set("views", path.join(__dirname, "views")); app.set("view engine", "ejs"); app.use(express.urlencoded({ extended: true })); app.use(methodOverride("_method")); main().then(() => { console.log("Connected to DB"); }).catch((err) => { console.log('Error while connecting to DB'); }); async function main() { mongoose.connect('mongodb://127.0.0.1:27017/wanderlust'); } app.listen(8080, () => { console.log("Server is listening on port 8080"); }); // Route Root app.get("/", (req, res) => { res.send("Hey I am Root"); }); // Route All Listings app.get("/listings", async (req, res) => { let allListings = await Listing.find(); res.render("listings/index.ejs", { allListings }); }); // Route New Listing app.get("/listing/new", (req, res) => { res.render("listings/newListing.ejs"); }); // Route Show Listing app.get("/listings/:id", async (req, res) => { let { id } = req.params; let data = await Listing.findById(id); res.render("listings/show.ejs", { data }); }); // Route Save New Listing app.post("/listings", async (req, res) => { let listing = new Listing(req.body.Listing); await listing.save(); res.redirect("/listings"); }); app.get("/listings/:id/edit", async (req, res) => { let { id } = req.params; let listing = await Listing.findById(id); res.render("listings/edit.ejs", { listing: listing }); }); app.put("/listings/:id", async(req, res) => { let listing = new Listing(req.body.Listing); console.log(listing); res.send("Working"); });
package.json内容
{ "name": "wanderlust", "version": "1.0.0", "description": "its a bnb website", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Vicky Girm", "license": "ISC", "dependencies": { "ejs": "^3.1.9", "express": "^4.18.2", "method-override": "^3.0.0", "mongoose": "^8.0.3" } }
问题描述
使用nodemon启动服务器后,首次请求所有路由均正常,但第二次或第三次访问不同页面或同一路由(如查看第三个/listings/:id页面)时,出现「localhost拒绝连接」错误,终端提示返回Promise但我已使用async/await;重启nodemon后该页面可正常访问,恳请帮忙排查问题。
排查及修复方案
1. 修复MongoDB连接逻辑
你的main函数中调用mongoose.connect时未使用await,虽然函数标记为async,但数据库连接Promise未被等待,可能导致服务器在数据库未完全连接时就开始处理请求,后续连接不稳定引发崩溃。修改为:
async function main(){ await mongoose.connect('mongodb://127.0.0.1:27017/wanderlust'); }
2. 为异步路由添加错误捕获
所有使用async/await的路由均未处理异常,一旦数据库操作出错(如查询不存在的ID、数据验证失败),会抛出未捕获的Promise拒绝,直接导致服务器终止。以/listings/:id路由为例,修改为:
app.get("/listings/:id",async (req,res)=>{ try{ let {id}=req.params; let data=await Listing.findById(id); if(!data){ return res.status(404).send("Listing not found"); } res.render("listings/show.ejs",{data}); }catch(err){ console.error("Show route error:", err); res.status(500).send("Server error"); } });
其余异步路由(/listings、/listings/:id/edit、POST/PUT路由)都需要添加类似的try/catch块,避免未处理错误导致服务器挂掉。
3. 修正PUT路由的业务逻辑
当前PUT路由仅创建了新的Listing实例,未执行更新操作,也未关联目标ID,且无错误处理。修改为标准的更新逻辑:
app.put("/listings/:id",async(req,res)=>{ try{ let {id}=req.params; // 查找并更新,返回更新后的文档,同时运行验证器 let updatedListing=await Listing.findByIdAndUpdate(id, req.body.Listing, {new:true, runValidators:true}); if(!updatedListing){ return res.status(404).send("Listing not found"); } res.redirect(`/listings/${id}`); }catch(err){ console.error("Update route error:", err); res.status(500).send("Failed to update listing"); } });
4. 查看完整错误日志
当出现连接拒绝时,nodemon终端会输出具体错误信息(如未捕获异常、数据库连接错误等),这些信息是定位问题的关键,务必仔细查看。
内容的提问来源于stack exchange,提问作者Vicky Giram
相关产品推荐
相关产品推荐

