项目白屏错误监控

1,286 阅读3分钟

背景

在前端项目中,当访问空对象的属性、或者空函数调用时,会导致渲染异常,出现白屏的情况,直接导致产品不可用,严重影响了用户体验。白屏错误出现的概率小,但是严重级别高,因此需要对白屏错误做一个拦截,引导用户在白屏情况下可以做什么,如:联系负责人、刷新页面等。

目标

  1. 拦截白屏错误,当页面出现白屏时,渲染备用UI,引导用户联系负责人或者刷新页面。
  2. 对错误信息进行上报。

错误拦截方案调研

方案一 React错误边界

使用React错误边界处理错误,利用统一的高阶组件包裹业务组件。

import React, { ErrorInfo } from 'react';
interface IState {
    hasError: boolean;
    error: Error | null;
    errorInfo: ErrorInfo | null;
}
export function withErrorHandler(Component, ErrorComp?) {
    class WithErrorHandler extends React.Component<any, IState> {
        constructor(props) {
            super(props);
            this.state = {
               hasError: false,
                // 错误信息,是否需要展示出来呢?
                error: null,
                errorInfo: null,
            };
        }
    public componentDidCatch(error, info) {
        this.setState({ hasError: true, error, errorInfo: info });
            // 监控上报错误
        }
    public render() {
        if (this.state.hasError) {
            return (ErrorComp || <div style={{padding: '20px'}}>出现了严重错误,无法渲染</div>);
            }
            return <Component {...this.props} />;
        }
    }
    WithErrorHandler.displayName = `withErrorHandler(${Component.displayName})`;
    return WithErrorHandler;
}

方案二 使用插件

github.com/gaearon/rea…

使用插件react-transform-catch-errors。

安装 babel-plugin-react-transform 和 react-transform-catch-errors

配置.babelrc参考如下:

{

"presets": ["es2015", "stage-0"],

"env": {

// only enable it when process.env.NODE_ENV is 'development' or undefined

"development": {

"plugins": [["react-transform", {

"transforms": [{

"transform": "react-transform-catch-errors",

// now go the imports!

"imports": [

// the first import is your React distribution

// (if you use React Native, pass "react-native" instead)

"react",

// the second import is the React component to render error

// (it can be a local path too, like "./src/ErrorReporter")

"./src/ErrorReporter"

// the third import is OPTIONAL!

// when specified, its export is used as options to the reporter.

// see specific reporter's docs for the options it needs.

// it will be imported from different files so it either has to be a Node module

// or a file that you configure with Webpack/Browserify/SystemJS to resolve correctly.

// for example, see https://github.com/gaearon/babel-plugin-react-transform/pull/28#issuecomment-144536185

// , "my-reporter-options"

]

}]

// note: you can put more transforms into array

// this is just one of them!

}]]

}

}

}

方案三 自定义React.createElement

写一个错误组件,重写React.createElement。使用 babel-plugin-transform-react-jsx 来更改 jsx 转化逻辑,将 jsx 用到的 createElement 替换成自己写的createElement方法。

错误监控上报

上报方案

使用的是内部工具上报。大概流程是:将Error对象进行上报,然后再接入Source Map,这样即可查看错误并定位到代码。

上报内容

  • 所在页面url
  • path
  • 路由参数
  • 当前用户
  • 时间
  • 错误类型
  • 错误描述
  • 堆栈信息

数据分析

我们将数据生成报表,观察到报错信息里,发生ChunkLoadError的错误居多。分析后,发现存在如下几种错误原因:

  • 浏览器无法找到文件或者文件已经过时。可能是因为项目上线了一次,但是用户停留在旧页面,访问的时候,旧文件已经不存在了。
  • 网络原因。可能是网络突然断掉。

总结

  1. 前端异常监控解决方案研究
  2. 前端异常处理
    5.前端白屏监控探索
  3. How to Solve the Chunk Load Error in JavaScript