请问,我们在开发前端项目的时候:
比如要通过如下的一个栈,一层一层地请求API
组件层
store层
api层
我们知道这一串请求,达到某个层级如果崩溃的话,我们可以通过try/catch进行捕获异常,我们可以向上进行throw异常,请问一般我们应该在哪里进行处理这个异常呢? 我可以把异常弹窗展示。
请问,我们在开发前端项目的时候:
比如要通过如下的一个栈,一层一层地请求API
组件层
store层
api层
我们知道这一串请求,达到某个层级如果崩溃的话,我们可以通过try/catch进行捕获异常,我们可以向上进行throw异常,请问一般我们应该在哪里进行处理这个异常呢? 我可以把异常弹窗展示。
早先我也遇到过类似的“在哪里处理”的问题。
不过我纠结的“处理”和你的不一样,我的观点是:所有中间层都不应该把错误藏起来(你可以当它不存在,但不能 catch
了却不抛出,这样不便于 debug),除非你 try...catch
的本意就是处理程序边界,我遇到的主要问题在于:
别人的解决方法我不知道,我自己是在公共请求方法里把 Error 封装了一层,并且用 getter
拦截并检测读取信息的行为:
class ResponseError {
#message = "";
#processed = false;
#originError!: Error;
#level:"info"|"warning"|"error" = "error";
constructor(error: Error, level?: "info"|"warning"|"error"){
this.#originError = Error;
if(level) this.#level = level;
setTimeout(() => {
if(this.processed) return; // 被别处处理过了,就不用管
// 尚未处理,弹提示信息,然后抛出
Message[this.#level](Error.message);
throw error;
}, 80) // 凡在这个时间点前进行的处理,都能检测到
}
// 别处代码尝试读取这个信息的时候调用
getter message(){
this.#processed = true; // 检测到读取行为,标为已处理
if(process.env.ENV = "development"){
console.warn("一个错误信息被读取了,其默认提示被取消")
}
return this.#originError.message;
}
}
👆这只是简化的原理演示,实际上我是做了一个工厂函数返回了一个 Proxy
。
楼上的做法也是有参考性的, http 请求在公共请求方法里处理。但是很可惜,我们的后端把所有他能控制的错误都包装成了 500 ,只有网关的错误是正确的 http 错误,所以我必须考虑 500 状态的几乎所有可能性。
这里的思路核心是:谁的异常谁处理。
比如,你有一个删除的按钮,删除的时候会弹出一个 confirm modal,然后用户点击了“确认”。那么,这个异常就是你的。如果删除失败,不管是任何一个环节失败,都应该在你的删除函数里处理。所以也应该在删除函数里捕获,其它地方都当它不会出错来跑就行,因为错误会强行清栈。
当然,有极个别的错误可以放到全局统一处理。比如 401,在请求层捕获然后跳转到登录页面或者弹出登录窗口也行。但是,我们必须考虑用户状态中途失效,而用户已经进行了一些操作需要保存这种情况,所以,我的建议仍然是,谁的错误谁处理,不要嫌麻烦。
6 回答5.3k 阅读✓ 已解决
9 回答9.5k 阅读
3 回答10.6k 阅读✓ 已解决
4 回答7.5k 阅读
5 回答8.4k 阅读
2 回答10.5k 阅读✓ 已解决
2 回答6.6k 阅读✓ 已解决
自己捕捉自己的异常。
网络请求相关的异常,统一的错误处理应该在拦截器里面配置好,并且返回好对应的 Promise 状态到调用的业务。一般我会把
401
、403
、500
之类的异常处理直接在拦截器里面配置弹窗提醒。组件和 Store 层一般就只会有业务逻辑错误的捕捉。不会出现说某一个网络请求异常,比如说超时或者其他的原因,导致整个业务逻辑不能正常执行,在控制台抛出
throw Error
。