node-fetch HTTP错误无法正常捕获,CheckResponseStatus未执行问题求助
问题原因
- node-fetch 仅在网络连接层面出现故障时才会返回rejected状态的Promise,包括目标服务未启动导致的
ECONNREFUSED、DNS解析失败、请求超时、跨域拦截等场景。而HTTP 4xx/5xx这类业务状态码属于请求已成功发送、且收到服务端响应的情况,fetch会判定为请求成功,进入.then链执行后续逻辑。 - 你遇到的
ECONNREFUSED是典型的网络连接失败错误,fetch直接进入rejected状态,跳过了.then链里的checkResponseStatus函数,直接触发catch执行ServerError,所以你看不到自定义抛出的HTTP状态错误。 - 补充潜在问题:代码同时混用async/await和.then/.catch写法,若
checkResponseStatus、ServerError未正确挂载到当前this指向的实例上,后续可能出现方法未定义的报错。
解决建议
1. 错误类型区分处理
在错误处理逻辑中增加错误类型判断,分别处理网络错误和HTTP业务错误,参考代码如下:
// 原有checkResponseStatus逻辑调整,增加错误类型标记方便后续区分 checkResponseStatus(res) { if(res.ok){ return res } else { const err = new Error(`The HTTP status of the response: ${res.status} (${res.statusText})`); err.type = 'HTTP_ERROR'; err.status = res.status; throw err; } } // 错误处理函数增加分支逻辑 ServerError(err){ // 处理网络连接错误 if (err.name === 'FetchError' && err.code === 'ECONNREFUSED') { console.log('Cannot connect to Server. Check you are using the correct IP Address and the server is running.'); } // 处理HTTP业务状态错误 else if (err.type === 'HTTP_ERROR') { console.log(`Server returned error: ${err.message}`); } // 兜底处理其他未知错误 else { console.log('Unknown request error'); } console.log(err); } // 建议统一用async/await写法,逻辑更清晰,避免this指向混乱 async function getStatus(serverip,serverport){ try { const res = await fetch(`http://${serverip}:${serverport}/api/outputs`); const validRes = this.checkResponseStatus(res); return await validRes.json(); } catch (err) { this.ServerError(err); // 按需决定是否向上层抛出错误 // throw err; } }
2. 可选:统一错误格式封装
如果需要所有错误都走统一的格式输出,可以在catch层先对原生网络错误做包装,再传给错误处理函数:
catch (err) { let processedErr; // 包装原生网络错误 if (err.name === 'FetchError') { processedErr = new Error(`Connection failed: ${err.message}`); processedErr.type = 'NETWORK_ERROR'; } else { processedErr = err; } this.ServerError(processedErr); }
3. this指向校验
如果运行时出现方法未定义的报错,说明当前this指向不符合预期,可直接改为普通函数调用,或提前绑定正确的this指向。
内容的提问来源于stack exchange,提问作者joepool
相关产品推荐
相关产品推荐

