fetch()函数错误捕获最佳方法及then()中错误处理疑问
嘿,我来帮你把fetch错误捕获的事儿说透——这里有个很多人刚用fetch都会踩的坑,先给你点明:fetch只有在真的连不上服务器的时候才会触发reject(比如断网、域名写错了),像404找不到资源、500服务器内部错误这类HTTP状态码错误,它根本不会进入你then里的err回调,反而会正常返回一个response对象,只是这个对象的ok属性是false。
最佳错误捕获方式:统一用
catch()兜底,加上HTTP错误判断 你当前的代码存在两个问题:一是没法捕获HTTP错误,二是每个then里加err回调会让代码冗余,还可能漏掉某些错误。推荐的做法是:
- 在第一个then里先判断response的
ok状态,把HTTP错误主动转为reject - 用一个统一的
catch()来捕获整个Promise链上的所有错误(网络错误、HTTP错误、JSON解析错误、后续处理函数的错误)
修改后的代码示例
const endpoint = 'http://localhost:3030/api/hotels'; fetch(endpoint) .then(res => { // 先处理HTTP错误:如果response不是ok状态,主动抛出错误 if (!res.ok) { throw new Error(`HTTP error! Status: ${res.status}`); } return res.json(); }) .then(parseRooms) .catch(err => { // 这里会捕获所有错误:网络故障、HTTP错误、JSON解析失败、parseRooms里的错误 console.error('请求或处理出错:', err); });
为什么不需要在每个then里加err回调?
- Promise的
catch()会捕获整个链上所有未被处理的reject,包括:- fetch本身的网络错误(比如断网)
- 我们主动抛出的HTTP错误(比如404、500)
res.json()解析失败(比如返回的不是合法JSON格式)parseRooms函数里抛出的任何同步/异步错误
- 每个then加err回调会让代码分散,而且如果某个then里的回调抛出错误,下一个then的err回调不一定能捕获到,不如统一用catch简洁可靠。
额外小技巧:区分错误类型
如果需要针对不同错误做不同处理,可以在catch里判断错误的类型或信息:
.catch(err => { if (err.message.includes('HTTP error')) { console.error('服务器返回错误:', err); } else if (err.name === 'TypeError') { // 一般网络错误会是TypeError,比如"Failed to fetch" console.error('网络连接失败:', err); } else { console.error('其他处理错误:', err); } });
内容的提问来源于stack exchange,提问作者Артем Мирошниченко
相关产品推荐
相关产品推荐

