Express localhost:5000服务添加catch块触发多报错排查
报错根因
三个报错均来自服务端路由代码的书写错误,客户端代码无问题:
TypeError: Cannot read property 'catch' of undefined:同步语句console.log(req.query)被错误插入到Promise链式调用中间,直接打断了调用链。axios().then()执行后返回Promise对象,但换行书写的console.log(req.query)是独立同步代码,返回值为undefined,后续的.catch()实际是尝试调用undefined上的方法,直接触发同步类型错误。Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client:上述同步错误抛出后,路由函数未做捕获,Express会自动向客户端返回500错误响应。等axios异步请求返回结果、执行.then()中的res.send(response.data)时,响应已经发送完成,触发重复发送响应的错误。UnhandledPromiseRejectionWarning:由于Promise链被打断,书写的.catch()并未挂载到axios请求返回的Promise实例上。一旦axios请求失败(包括未传token直接访问路径、Mavenlink接口返回错误、网络异常等场景),请求错误没有对应的捕获逻辑,直接抛到全局触发未捕获Promise拒绝警告,严重时会直接导致Node进程崩溃。
修复方案
调整服务端代码,不要在Promise链式调用的.连接位置插入无关代码,同时在错误捕获分支中补充正常的响应返回逻辑,避免请求挂起或重复响应。
修复后的服务端代码如下:
const axios = require('axios'); const router = require('express').Router(); router.get('/mavenlink', (req, res) => { const headers = { Authorization: `Bearer ${req.query.token}`, }; // 同步日志移到Promise链外部,不要打断链式调用 console.log(req.query) axios({url:"https://api.mavenlink.com/api/v1/workspaces.json", headers: headers}) .then((response) => { // 增加响应状态判断,避免重复发送响应 if (!res.headersSent) { res.send(response.data) } }) .catch((error) => { console.log(error); // 错误场景必须返回响应,避免请求挂起 if (!res.headersSent) { res.status(500).send({ msg: '请求mavenlink接口失败', error: error.message }) } }); }) module.exports = router;
补充说明
- 原有客户端代码无语法或逻辑问题,服务端修复后即可正常拉取数据。
- 直接访问
localhost:5000/mavenlink未携带token参数时,服务会正常返回错误响应,不会再触发进程崩溃。 - 后续如果使用async/await写法编写路由,需要将整个异步逻辑包裹在try/catch块中,避免遗漏错误捕获。
内容的提问来源于stack exchange,提问作者Michael Stubbs
相关产品推荐
相关产品推荐

