获取Firebase文档时抛出的错误未被catch捕获该如何解决?
问题原因
- 核心原因1:Error对象无法被直接JSON序列化。你在路由的catch回调中直接把Error实例传给
res.send(),Express序列化后会得到空对象{},看起来就像错误没有被捕获到一样,实际上catch逻辑已经执行了。 - 核心原因2:Promise链的catch位置不合理。你把错误捕获放在了文档存在性判断逻辑的前面,只能捕获到获取文档请求阶段的错误,虽然文档不存在抛出的错误依然会作为整个Promise的rejection状态向外传递,但中间的catch吞掉了原始错误信息,也提升了排查成本。
- 附加原因:路由处理函数标记了
async但没有配合await使用,部分Express版本对async函数内未返回的Promise处理存在兼容问题,也可能导致错误被静默吞掉。
修复方案
1. 调整getCustomerForReal函数的Promise链结构
把catch移到整个Promise链的末尾,统一捕获所有阶段的错误,同时保留原始错误信息方便排查:
function getCustomerForReal(customerId): Promise<Customer> { return Promise.resolve() // neutral starter promise .then(() => { const customerDocument = fb.customersCollection.doc(customerId).withConverter(customerConverter); if(customerDocument) { return customerDocument.get() } else { throw new Error("获取文档引用失败"); } }) .then(doc => { if (doc.exists) { return doc.data() as Customer; } else { throw new Error('文档不存在'); } }) .catch(error => { throw new Error(`获取文档错误:${error.message}`); }); };
2. 调整路由处理逻辑
两种可选写法,都需要注意不要直接返回Error实例,而是返回结构化的错误信息:
写法一:移除async关键字,使用纯Promise写法
customerRouter.get('/get/:customerId/', express.json(), function (req, res) { customerApi.getCustomerForReal(req.params.customerId) .then(customer => { console.log(customer) res.status(200).json(customer) }) .catch(error => { console.log(error) res.status(400).send({ code: 400, message: error.message }) }) });
写法二:使用async/await语法,代码更简洁易读
customerRouter.get('/get/:customerId/', express.json(), async function (req, res) { try { const customer = await customerApi.getCustomerForReal(req.params.customerId) console.log(customer) res.status(200).json(customer) } catch (error) { console.log(error) res.status(400).send({ code: 400, message: error.message }) } });
内容的提问来源于stack exchange,提问作者radishhorse
相关产品推荐
相关产品推荐

