优雅的统一处理axios错误

2,312 阅读2分钟

在vue项目中,我们一般会用到axios请求库,在每个页面中,我们也一般会需要发送请求,只要是请求,就有可能会报错,一些人可能会选择在发请求的地方去捕捉错误,即使他不关心报错,也必须要捕捉错误,因为如果不捕捉,如果有错误却没有被处理的话,控制台会报错。但是在每个页面的每个请求中都去捕捉错误,是很麻烦的事,对我而已,多次写catch,在catch中填充一个空函数,我也会觉得麻烦。 还有另外一些人,可能会在axios响应拦截器中统一进行错误处理,但是对于某些页面的错误需要特殊处理的时候,这种方式又显得灵活性不够,怎么合理的处理好这两种显得有些矛盾的需求,也是困惑了我好久,终于,我找到了觉得还算优雅的方式。我的代码如下


const HandleType = {
  unHandled: 0,
  then: 1,
  catch: 2
}
class DefaultErrorHandlerPromise{
  constructor(promise, defaultErrorHandler) {
    this.defaultErrorHandler = defaultErrorHandler
    this.origin = promise
    promise.catch((err) => {
      if (this.handleType === HandleType.unHandled) {
        this.defaultErrorHandler?.call(null, err)
      }
    })
    this.handleType = HandleType.unHandled
  }

  then(sucessHandler, errorHandler) {
    if (errorHandler != null) {
      this.handleType |= HandleType.catch
    } 
    if(sucessHandler != null) {
      this.handleType |= HandleType.then
    }
    const promise = this.origin.then(sucessHandler, errorHandler)
    return new DefaultErrorHandlerPromise(promise, this.defaultErrorHandler)
  }

  catch(errorHandler) {
    this.handleType |= HandleType.catch
    const promise = this.origin.catch(errorHandler)
    return new DefaultErrorHandlerPromise(promise, this.defaultErrorHandler)
  }
}

在统一请求的地方,需要这么写

export const request = (config){
  return new DefaultErrorHandlerPromise(service.request(config), () => {
    console.log('统一处理');
  });
};
   

这样在页面发请求时,如果我们不关心错误,就不需要写catch语句,这样就会走统一的错误处理流程,如果你想有不同的错误处理逻辑,就可以在catch语句中写上你的错误处理逻辑。这样会不会觉得优雅了一些呢?如下面的示例

    request(xxx).then().catch(err => console.log('单独进行错误处理'))
    Promise.all([request(xxx)]).then().catch(err => console.log('单独进行错误处理'))