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

使用Express与Mongoose从MongoDB取单条数据时,无数据应用崩溃求助

Express查询MongoDB不存在对象时应用崩溃的解决办法

问题描述

使用Express从MongoDB数据库获取对象,对象存在时可正常返回数据,但对象不存在时,尝试返回自定义文本/页面或执行其他操作时,应用直接崩溃,跳转到显示<the path> 404 This page could not be found. Page Developed by @yandeu的页面。

尝试的代码示例1:

app.get("/item/:id",(req,res)=>{
    Item.findById(req.params.id).then((item)=>{
        if(item){
            res.json(item)
        }else{
            res.sendStatus(404) 
            // 也试过以下写法:
            // item = {"Status":"not Found"}
            // res.json(item) 
            // res.send("404 page")
            // res.sendFile(__dirname+"/404.html")

        }
    }).catch(err =>{ 
        if(err){
            throw err
        }
    })
})

尝试的代码示例2(使用try/catch仍无效):

app.get("/item/:id",(req,res)=>{
    try{
        Item.findById(req.params.id).then((item)=>{            
        res.json(item)
        })
    }
    catch(err){
        if(err){
            throw err
        }
        console.log("not found")
    }
})

错误原因

  1. catch块抛出错误导致崩溃:第一个示例中,.catch捕获到错误后直接throw err,这会触发Express的默认错误处理机制,若你引入了第三方404中间件(如@yandeu的页面),就会跳转到该页面,同时未处理的报错会导致应用崩溃。
  2. 同步try/catch无法捕获异步Promise错误:第二个示例中,try/catch包裹的是findById的调用,但findById返回的是Promise对象,异步错误无法被同步的try/catch捕获,错误依然未被处理。

解决方案

方案1:正确处理Promise的catch回调

不在catch块中抛出错误,而是直接返回自定义响应:

app.get("/item/:id", (req, res) => {
  Item.findById(req.params.id)
    .then((item) => {
      if (item) {
        res.json(item);
      } else {
        // 选择一种自定义404响应方式
        res.status(404).json({ Status: "物品不存在" });
        // 或返回自定义页面
        // res.status(404).sendFile(__dirname + "/404.html");
        // 或返回文本
        // res.status(404).send("404 - 未找到指定物品");
      }
    })
    .catch((err) => {
      // 处理查询过程中的异常(如ID格式非法)
      console.error("查询出错:", err);
      res.status(500).json({ Status: "服务器错误", 详情: err.message });
    });
});

方案2:使用async/await简化异步错误处理

通过async/await将异步代码转为同步写法,让try/catch能捕获所有错误:

app.get("/item/:id", async (req, res) => {
  try {
    const item = await Item.findById(req.params.id);
    if (item) {
      res.json(item);
    } else {
      res.status(404).json({ Status: "物品不存在" });
      // 替换为你需要的自定义响应
    }
  } catch (err) {
    console.error("查询出错:", err);
    res.status(500).json({ Status: "服务器错误", 详情: err.message });
  }
});

额外注意事项

  • 检查是否引入了第三方404中间件,若不需要可直接移除;若需保留,需确保该中间件定义在所有路由之后,这样自定义的404响应会优先触发。
  • 不要在Express路由处理函数中直接throw err,除非你配置了自定义错误处理中间件来捕获处理,否则会导致应用崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 18:41:13