
## 作用
浏览器错误信息收集

## 用法



### 配置篇

对应sourcemap的上传包[@_gz/upload-sourcemap](https://www.npmjs.com/package/@_gz/upload-sourcemap)

const uploadSourceMap = require('@_gz/upload-sourcemap');

create-react-app配置:
文件:congif/env.js:
```javascript
{
    // Useful for determining whether we’re running in production mode.
    // Most importantly, it switches React into the correct mode.
    NODE_ENV: process.env.NODE_ENV || 'development',
    // Useful for resolving the correct path to static assets in `public`.
    // For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
    // This should only be used as an escape hatch. Normally you would put
    // images into the `src` and `import` them in code to get their paths.
    PUBLIC_URL: publicUrl,
    // 在这里添加process.env环境变量
    COMMITHASH: new uploadSourceMap().gitCommitHash,
}
```

umi 配置: 
```javascript

const { UMI_ENV } = process.env
define: {
    'process.env': {
      UMI_ENV: UMI_ENV, // 环境变量(纯粹保留以前变量，根据自己项目改变)
      COMMITHASH: new uploadSourceMap().gitCommitHash
    }
  },
```
vue.config.js 配置
```javascript
chainWebpack: (config) => {
  config.plugin('define').tap((args) => {
    args[0]['process.env'].COMMITHASH = JSON.stringify(new uploadSourceMap().gitCommitHash);
    return args;
  });
}

```

 ### 使用案例

vue
```javascript
import initError, { parseStack, errorHandler } from '@_gz/browser-error';
/***
 * @param {String}  url    接口地址(必填)
 * @param {String}  projectName    项目名称(必填)
 * @param {Object}  params    项目其他需要传的数据(非必填)
 * 
 * */
initError({
  url: '错误上报接口地址',
  projectName: '项目名称'
});


// vue
Vue.config.errorHandler = function(err, vm, info) {
  // vm为抛出异常的 Vue 实例
  // info为 Vue 特定的错误信息，比如错误所在的生命周期钩子
  // err 错误信息 堆栈， 如果不抛出err 否则错误信息不会打印到控制台
  const { message, source, line, column, stack } = parseStack(err);
  errorHandler(message, source, line, column, stack);
  console.error(err);
};

```

umi
```javascript
// 新建错误边界组件
import React, { ErrorInfo, Props } from 'react';
import { errorHandler, parseStack } from '@_gz/browser-error';

class ErrorBoundary extends React.Component {
  constructor(props: Props<any>) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error: boolean) {
    // 更新 state 使下一次渲染能够显示降级后的 UI
    return { hasError: true };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    // 错误日志上报
    console.log('componentDidCatch----error', error);
    console.log('componentDidCatch----errorInfo', errorInfo);

    const { message, source, line, column, stack } = parseStack(error);
    errorHandler(message, source, line, column, stack);
  }

  render() {
    // @ts-ignore
    if (this.state.hasError) {
      // 你可以自定义降级后的 UI 并渲染
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

export default ErrorBoundary;


// 需要在最开始项目 初始化
import initError from './sdk';
initError({
  url: 'http://127.0.0.1:3000/errors',
  projectName: 'umi-main',
});

// 导入错误边界
import ErrorBoundary from '@/ErrorBoundary';

// 包裹最外层，以下是umi的方式，具体其他项目，可参考实现
export function rootContainer(container: React.FunctionComponentElement<{}>) {
  return React.createElement(ErrorBoundary, null, container);
}

```

### 上传参数:


* @param {String}  message    错误信息
* @param {String}  source    出错文件
* @param {String}  sourceName  文件名称
* @param {Number}  line    行号
* @param {Number}  column    列号
* @param {Object}  stack  错误堆栈信息
* @param {String}  projectName  项目名称
* @param {String}  commitHash  git commit hash


### 上传格式:
```javascript
{
    errors:[{
        ...
    }]
    // 如果没有params，不传
    params:{}
}
```


### 说明

- [x] 是否上报 js 报错
- [ ] 是否上报 API 接口请求
- [ ] 是否上报资源请求
- [ ] 是否上报页面 PV
- [ ] 是否上报页面性能
- [ ] 内置支持自定义日志上报

#### 注意事项

 - 一定要走生产模式，开发模式下的对应报错映射文件并不同，且收集时会报错, 请谨慎选择;
 - 错误边界组件理论上适用于所有react组件，creat-react-app如果出现因懒加载方式或个别webpack配置产生无法上报的情况，可添加错误边界组件再次尝试;