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

API请求无数据时抛出new Error致应用崩溃,返回JSON状态正常求解决

问题原因与解决方案

核心原因

直接throw new Error()导致应用崩溃,本质是未被捕获的错误(尤其是异步场景下)触发了Node.js的未处理错误机制:

  • 如果你的路由处理函数是异步函数(用了async/await),里面抛出的错误会变成未处理的Promise拒绝,Node.js默认会终止进程(即应用崩溃),因为它无法自动将异步错误传递给Express的错误处理逻辑。
  • 而直接返回带状态码的JSON是正常响应请求,不会触发未捕获错误流程,所以应用能正常运行。

解决步骤

1. 正确传递异步错误到Express错误处理链

在异步路由处理函数中,必须手动捕获错误并传给next(),而不是直接throw:

// 示例异步路由
app.get('/api/your-resource', async (req, res, next) => {
  try {
    const data = await yourDatabaseQueryOrApiCall();
    if (!data) {
      // 抛出自定义错误
      throw new Error('未获取到所需信息');
    }
    res.json(data);
  } catch (err) {
    // 将错误传递给错误处理中间件
    next(err);
  }
});

2. 配置自定义错误处理中间件

必须定义一个带4个参数的中间件(err, req, res, next),且要放在所有路由之后:

// 错误处理中间件
app.use((err, req, res, next) => {
  // 打印错误栈用于调试
  console.error(err.stack);
  // 返回自定义错误响应
  res.status(404).json({
    success: false,
    message: err.message || '服务器内部错误'
  });
});

3. 可选简化方案:使用express-async-errors

如果不想写大量try/catch,可以安装express-async-errors包,它会自动捕获异步路由中的错误并传递给next():

npm install express-async-errors

然后在项目入口文件引入:

require('express-async-errors');

之后异步路由里直接throw错误即可,无需手动try/catch:

app.get('/api/your-resource', async (req, res) => {
  const data = await yourDatabaseQueryOrApiCall();
  if (!data) {
    throw new Error('未获取到所需信息');
  }
  res.json(data);
});

关键注意事项

  • 错误处理中间件必须是4个参数,少一个都会被Express当成普通中间件,无法捕获错误。
  • 同步代码中throw的错误,Express会自动捕获并传递给错误处理中间件,但异步代码必须手动处理或用工具包辅助。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:57:21