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
相关产品推荐
相关产品推荐

