本文讲解如何在 node.js api 中使用 got 发起 http 请求时,正确捕获并向上抛出错误,确保控制器能将有意义的错误响应(如 400/500 状态码及错误信息)返回给前端,而非静默吞掉异常导致 500 internal server error。
本文讲解如何在 node.js api 中使用 got 发起 http 请求时,正确捕获并向上抛出错误,确保控制器能将有意义的错误响应(如 400/500 状态码及错误信息)返回给前端,而非静默吞掉异常导致 500 internal server error。
在基于 async/await 的 Node.js 服务层中,错误处理的关键在于不中断错误传播链。你当前的服务函数中使用了 .catch() 捕获 got(options) 的拒绝(rejection),但仅执行 console.log() 后未重新抛出错误——这会导致 Promise 被“静默解析”为 undefined,后续 return response.body 将因 response 为 undefined 而报错,最终触发 Express 默认的 500 错误。
正确的做法是:在 try/catch 中统一处理异步错误,并在日志记录后主动 throw err,使错误原样冒泡至调用栈上层(即控制器)。以下是优化后的完整实现:
// service/squarePaymentService.js
async function deletePayment(paymentId) {
try {
const options = await ApiOptionsService.deleteItem(paymentId);
const response = await got(options); // 不再使用 .catch()
return response.body;
} catch (err) {
console.error('[deletePayment] Got request failed:', {
message: err.message,
code: err.code, // e.g., 'ENOTFOUND', 'ETIMEDOUT'
statusCode: err.response?.statusCode, // if got a response with error status
url: err.options?.url
});
throw err; // ✅ 关键:必须重新抛出,否则错误被吞没
}
}
对应控制器保持简洁可靠(推荐统一使用 async/await 风格):
// controller/paymentController.js
router.delete('/deletePayment/:id', async (req, res, next) => {
try {
const paymentResponse = await squarePaymentService.deletePayment(req.params.id);
res.json(paymentResponse); // 或 res.send()
} catch (err) {
// 可选:根据错误类型定制响应状态码
const statusCode = err.statusCode >= 400 && err.statusCode <p>⚠️ 注意事项:</p>
- 避免混用 .catch() 和 await:.catch() 会将 rejection 转为 resolved,破坏 await 的语义;应优先使用 try/catch。
- 不要忽略 err.response:Got 对非 2xx 响应默认抛出 HTTPError,其 err.response.body 可能含上游服务的错误详情,建议一并记录或透传。
- 区分错误类型:可基于 err.code(网络层)或 err.response?.statusCode(业务层)做精细化处理,例如将 404 映射为 { error: true, code: 'PAYMENT_NOT_FOUND' }。
- 全局错误中间件兜底:确保已配置 Express 全局错误处理器(app.use((err, req, res, next) => {...})),以防未捕获异常导致进程崩溃。
通过以上结构,你既能获得清晰的日志追踪能力,又能保证前端始终收到结构化、可解析的错误响应,大幅提升 API 的健壮性与可观测性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











