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

Node.js Promise拒绝时错误消息无法正常捕获问题咨询

问题原因与解决方案

我来帮你拆解这个问题,主要有两个核心原因导致错误消息无法正常传递:

1. 内部catch吞掉了错误

看你的addBrand函数里的这段代码:

return tools.execSQLQuery(query)
  .then(result => result[0])
  .catch(err => console.log(err))

当tools.execSQLQuery抛出错误时,这个内部的catch只做了打印日志的操作,但没有重新抛出错误。这会导致Promise从rejected状态强制转为resolved状态,后续调用方的.catch根本捕获不到这个错误,反而会进入.then分支(拿到undefined结果)。

另外你手动抛出的Promise.reject(new Error(...))其实是能正常传递的,但因为SQL查询的错误被吞了,再加上第二个问题,才会出现你看到的奇怪现象。

2. Error对象直接序列化JSON会丢失信息

JavaScript的Error对象的message等属性默认不是可枚举的,当你直接把err传给res.json()时,JSON.stringify无法正确提取它的属性,所以最终返回的是空对象{}。


修复方案

第一步:修复内部错误吞掉的问题

把内部的catch改成重新抛出错误,或者直接去掉内部catch(让错误自然冒泡到调用方处理):

exports.addBrand = function (user, data) {
  /** Mandatory data **/
  let name = "'" + data.brand.name + "'"
  let idAdvertiser = data.brand.idAdvertiser
  /** Optional data **/
  let isDefaultBillingEntity = data.brand.isDefaultBillingEntity === undefined ? null : data.brand.isDefaultBillingEntity
  if (name === undefined || idAdvertiser === undefined)
    return Promise.reject(new Error('A Brand name and an advertiser id should be provided')) // 顺便修正拼写错误:provide → provided
  return tools.execSQLQuery(query)
    .then(result => result[0])
    // 保留日志并重新抛出错误,让调用方捕获
    .catch(err => {
      console.log(err)
      throw err
    })
}

第二步:正确序列化Error对象

在调用方的catch里,不要直接返回err对象,而是提取它的message属性(或者其他你需要的信息):

var addBrand = (req, res) => {
  Brand.addBrand(req.user, req.body)
    .then(result => res.status(201).json({success: true, ui_info: 'Brand created.', ui_type: 'good', data: {brand: result}}))
    .catch(err => res.status(403).json({
      success: false, 
      message: err.message || 'Unknown error occurred' // 提取错误消息
    }))
}

这样修改后,无论是你手动抛出的参数错误,还是SQL查询的错误,都能正确传递到调用方,并返回包含正确错误消息的JSON响应了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:04:30