React中的错误处理

by Teobler on 06 / 09 / 2019

views

由于本文使用了比较通用的redux技术栈,所以本文默认读者对redux和redux的middleware相关的知识已经有足够的了解,所以本文不会就相关领域做展开讨论。

Error handler是一个项目中不得不做的一件事,不论是用户的错误操作还是网络请求发生异常,都需要一个机制来告诉用户 — 这里挂了,你待会再来。

而如果这个东西做的不好的话,就会散落在项目的各个地方,在任何你觉得会发生错误的地方,你都需要提前做好预防,防止未来系统在这里挂掉。如果这样的话,那么你的handler就会极难维护,错误处理的需求一变,你需要翻遍整个项目,去寻找那些散落在各处的“星星”。

Error Middleware With Redux

在项目中我们使用redux的中间件来管理error handling这件事。在redux的store中,我们使用redux提供的applyMiddleware接口将errorMiddleware与其他的middleware组合起来形成一个enhancer,然后在createStore的时候传进去。

错误处理流程

const createErrorMiddleware = (shouldHandleError: (action: AnyAction) => boolean) => {
  return ({ dispatch }: MiddlewareAPI) => {
    return (next: Dispatch) => {
      return (action: AnyAction) => {
        if (shouldHandleError(action)) {
          // do what you want
        }
        return next(action);
      };
    };
  };
};

首先由于是middleware,所以会拦截到所有的action,通常并不是所有的action都需要错误处理,所以我们会在一开始时通过shouldHandleError函数来判断这个action是否需要错误处理,不需要的话直接dispatch一个新的action给下游。

如果需要处理的话可以进一步判断这个action是哪一类错误,需要对其做什么处理等等,这一步往往跟业务强相关,不同的项目组会有不同的需求,需要“对症下药”。比较通用的做法是在拿到error message后在页面中将其显示出来,及时给用户一个反馈,告诉用户这时应该怎么做。

过滤

在有一些比较特殊的情况下我们并不想处理某个类型的错误,这时我们也会在shouldHandleError中进行错误action的过滤。通常可以设置一个标志位,当检测到这个标志位的时候就过滤掉这个action,不进行处理。

通知

错误发生之后,我们通常需要告诉用户我们的App发生了什么错误,或者告诉用户下次应该如何避免这样的错误。这时候就需要一个全局范围的通知信息,将错误信息显示出来,我们一般会选择Toast/Snack Bar作为错误信息的容器。

常见错误

比较常见的错误之一就是业务上的错误请求,比如参数错误,用户误操作发送请求等。这时通常后端会在response中塞入一个error message,我们就可以将error message或者设置在前端的一个默认错误信息放入一个错误的action中。当这个action被error middleware捕获到后就可以dispatch一个新的action通知用户发生了什么错误。

而其它的常见错误比如后端返回的各种状态码4XX/5XX等也会用相同的处理方式进行处理。

主动抛错

在一些情况下前端也需要主动抛出错误,告诉用户当前操作是违规操作,在不发请求的情况下主动抛出错误,提升用户体验。举个例子,比如在文件上传的时候,为了保护磁盘空间,往往会限制用户上传文件的大小。如果此时让后端来返回错误的话,其实文件已经上传了,实属没有必要,所以往往我们会在上传前检查文件大小,如果文件过大,我们便可以主动抛错,告诉用户从新上传一个小一些的文件。