返回

没有比道歉更能挽救事件回调系统的了

前端





当然,使用try-catch是没有问题的,但是既然我们正在开发,就应该得知具体的报错情况,并且处理掉,但是我们一旦使用try-catch就会帮我们静默的处理,并不会暴露错误,(chrome中有调试工具pause on caught exception只要出错就暂停到此处,使用try-catch就不能暂停到具体错误的地方)。

以下,我们来处理一些场景:

>1. 当我们代码出错的时候,我们要明确的定义错误类型,并且向外部抛出这个错误,然后就可以自定义解决这个错误了,我们常常写一个errorCode的常量去代表不同的错误,写了一个函数去抛出错误。

try{
functionname(xxx)
} catch(err) {
if(err.code === errorCode.aaa) {
//to do somethings
}
}
上面的代码可以捕获到我们抛出的错误,并根据错误类型做一些具体的处理,这种方式的实现起来很轻松,并且很灵活,而且针对特定的错误,我们可以做针对性的处理,方便了日后的维护。

>2. 但是,我们还是不能得知这个函数内部的逻辑,可能会报错的具体的情况,我们可以用vscode(提供有debug的功能)来调试错误,这就比较难了,毕竟要一边debug一边去查看代码;我们可以使用工具检测一下,但是只能检测的当时,修改完之后可能会再触发新的错误,也有可能不是新的错误,但是错误的触发条件发生了变化。

>3. 如果我们有一个不显式的异常的话,这个时候最常见的解决方案是使用try catch将错误捕获,然后再输出自定义的错误,我们对于输出的错误,写一个函数输出就可以了。

function outPuteror(err) {
   console.log(err.message)
}
后面我们函数出现问题后,就向函数中抛出异常,注意一定要保证这个函数是try catch过的,这样的话,才能保证我们的错误会被捕获到。


这样做在很大程度上解决了我们的问题,但是还是不够完美的,因为在处理错误的时候,我们可能会需要返回一些值,这种情况如果使用这种方式会很难实现,我们只好在出错的时候也返回一些固定的值,但是这样的话对于业务的开发造成了很大的不便,我们还有一种解决方案。

为了更好理解,我们来看一个例子:

>4. 比如现在我们有一个rpc服务,如果我们使用了try-catch并抛出了错误,并自己去捕获错误,那么这个报错的信息就会原封不动的发送给服务端,服务端是无法得知我们自己具体是如何处理的,而我们利用这个错误信息又无法定位到我们的代码中的具体位置。

5. 要想解决这个问题,我们就需要自定义我们的错误,而且自定义的错误必须继承Exception这个类,并且给这个类设置errorCode和message。

class CustomException extends Exception {
constructor(errorCode, message) {
super(message)
this.errorCode = errorCode;
}
}
我们自定义了错误类型,这个错误类型会携带自己的errorCode和message。当这个错误抛出的时候,它会被try-catch捕获,我们就可以根据这个错误的errorCode和message去做一些业务逻辑上的处理了,我们也可以对返回给客户端的值做一些处理,保证我们业务的顺利进行。

对于使用了这种机制之后,不管是服务端还是客户端,都可以更好的了解报错的情况,并且在控制台输出的日志也是我们自己自定义的,可以让我们更好的了解问题所在,如果我们在抛出错误的时候,只给出了错误的编码,那么还可以根据错误的编码做更多的处理。