持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
核心描述
- 了解 React 的异常处理,对业务来说有两个重要意义:
- 在用户使用过程中出现错误,可以进行友好的提示或降权处理
- 通过埋点上报的方式将发生异常的当时情况采集起来,方便我们及时处理和更好的复现、修复问题
- React 处理异常,仅考虑 16 以上版本,因为随着版本的不断迭代,一些旧的方法逐步会被废弃
- 错误边界(Error Boundaries):
- 定义:错误边界是一种 React 组件,可以捕获发生在其子组件树任何位置的 JavaScript 错误,并打印这些错误,同时展示降级 UI,而并不会渲染那些发生崩溃的子组件数
- 范围:错误边界可以捕获发生在整个子组件树的渲染期间、生命周期方法以及构造函数中的错误
- 用法:
- 在 class 组件中定义了
static getDerivedStateFromError()
,不允许副作用 componentDidCatch
:可以允许副作用
- 在 class 组件中定义了
- 以下错误场景无法捕获:
- 事件处理(如 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
- 或者根据实际项目中,自己做一个异常处理的封装
参考资料
- React 官方文档-错误边界:zh-hans.reactjs.org/docs/error-…
- React,优雅的捕获异常:juejin.cn/post/697438…
- 前端异常的捕获与处理:www.zoo.team/article/cat…
- catch-decorator :github.com/enkot/catch…
- catch-decorator-ts:github.com/valjic1/cat…
- catch-error-decorator:github.com/YeJIoOb/cat…
- async-catch-loader:github.com/yeyan1996/a…
- auto-inject-async-catch-loader:www.npmjs.com/package/aut…
- babel-plugin-promise-catcher: www.npmjs.com/package/bab…
浏览知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。