React 如何处理异常

509 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

核心描述

  • 了解 React 的异常处理,对业务来说有两个重要意义:
    • 在用户使用过程中出现错误,可以进行友好的提示或降权处理
    • 通过埋点上报的方式将发生异常的当时情况采集起来,方便我们及时处理和更好的复现、修复问题
  • React 处理异常,仅考虑 16 以上版本,因为随着版本的不断迭代,一些旧的方法逐步会被废弃
  • 错误边界(Error Boundaries):
    • 定义:错误边界是一种 React 组件,可以捕获发生在其子组件树任何位置的 JavaScript 错误,并打印这些错误,同时展示降级 UI,而并不会渲染那些发生崩溃的子组件数
    • 范围:错误边界可以捕获发生在整个子组件树的渲染期间、生命周期方法以及构造函数中的错误
    • 用法:
      • 在 class 组件中定义了 static getDerivedStateFromError() ,不允许副作用
      • componentDidCatch :可以允许副作用
    • 以下错误场景无法捕获:
      • 事件处理(如 onClick)
      • 异步代码(如 setTimeout)
      • 服务端渲染
      • 它自身抛出来的错误(并非它的子组件)
  • 使用 try ... catch :对可能出现问题的地方,主动捕获异常并做对应处理
  • 使用 window.onerror:捕获全局 JavaScript 异常
  • 使用 unhandledrejection:捕获 Promise 异常
  • 使用 window.addEventListener : 捕获全局静态资源异常
  • 使用 axios.interceptors:捕获 axios 请求器中接口异常,同理可以换成其他请求器或接口统一处理逻辑

知识拓展

  • JS 中的异常分类:
    • Error:错误的基类,其他错误都继承自该类型
    • EvalError:Eval 函数执行异常
    • RangeError:数组越界
    • ReferenceError:尝试引用一个未被定义的变量时,将会抛出此异常
    • SyntaxError:语法解析不合理
    • TypeError:类型错误,用来表示值的类型非预期类型时发生的错误
    • URIError:以一种错误的方式使用全局 URI 处理函数而产生的错误
  • 针对异常做好对应的上报,方便主动定位问题,也方便在用户报错时,获取更多的信息
    • 借助第三方开源库:badjs,sentry 等
    • 借助付费产品:arms、fundebug 等
    • 根据实际情况自研,可以考虑和性能监控一起结合起来,需要自研前端部分的上报SDK、数据接收和分析逻辑、数据分析管理后台等
  • 针对 React 的报错,还有一些其他的拓展:
    • 开源库:catch-decorator、catch-decorator-ts,仅仅捕获方法,处理比较初级
    • 开源库:catch-error-decorator,通过 AsyncFunction判断,提供失败后的默认返回值
    • 开源库:auto-inject-async-catch-loader、async-catch-loader、babel-plugin-promise-catcher
    • 或者根据实际项目中,自己做一个异常处理的封装

参考资料

浏览知识共享许可协议

本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。