::: tip
插件文档详细说明请参考 @shencom/plugins 文档
:::
初始化文件
# 安装依赖
yarn add @shencom/plugins
# 创建 setup/sentry.ts 文件,存在则用不创建
mkdir src/setup && touch src/setup/sentry.ts
# 创建 `src/setup/index.ts` 入口文件
touch src/setup/index.ts
添加下面代码
src/setup/sentry.ts
// 示例, 按需修改
import { VueConstructor } from 'vue';
import { Sentry } from '@shencom/plugins'; // 二次封装类
import router from '../router'; // 路由
const dsn = 'https://xxxx@sentry.shencom.cn/n';
/** 初始化 */
export default function install(Vue: VueConstructor) {
const { $utils, $config } = Vue.prototype as Vue;
const { _IsPro, _IsDev, _FormatDateTime } = $utils;
const { scid, version } = $config;
const release = version + (_IsPro ? '' : '.tst');
Sentry.install({
Vue,
dsn,
scid,
isDev: _IsDev,
isPro: _IsPro,
release,
BrowserTracingOption: {
routingInstrumentation: Sentry.context.vueRouterInstrumentation(router),
},
beforeSend(event) {
// 上报拦截,根据需要自定义上报数据
const base = {
scid,
date: _FormatDateTime(),
environment: _IsPro ? '正式' : '测试',
origin: window.location.origin,
hash: window.location.hash,
search: window.location.search,
};
// 上报 tag.name 可以通过当前用户名来查找全部出现异常的情况
// const user = _UserInfo._GetUserInfo() || {};
// const username = user.realname || user.nickname;
// if (username) {
// if (!event.tags) event.tags = {};
// Object.assign(event.tags, { username });
// }
if (!event.extra) event.extra = {};
Object.assign(event.extra, base);
return event;
},
});
}
src/setup/index.ts
import { VueConstructor } from 'vue';
+ import Sentry from './sentry';
export default function install(Vue: VueConstructor) {
+ Vue.use(Sentry);
}
src/main.ts
import Vue from 'vue';
...
+ import Init from './setup';
+ Vue.use(Init);
错误上报
::: tip
在 sentry.ts
中,进行初始化 @shencom/plugins
包的 Sentry 方法,根据需求进行改动;
通过创建一个 src/lib/utils/error.ts
文件,再进行集中处理不同类型的错误上报
:::
// src/lib/utils/error.ts
/* eslint-disable import/prefer-default-export */
import { AxiosError } from 'axios';
import { Sentry } from '@shencom/plugins';
const responseError = (error: AxiosError) => {
console.log('请求错误--- :', error, { ...error });
if (!error || !error.response) return;
const { response, message } = error;
const { config, data, status } = response;
const method = (config.method && config.method.toLocaleUpperCase()) || '';
Sentry.setRequest({
data,
status,
method,
message,
url: config.url || '',
body: JSON.parse(config.data || '{}'),
header: config.headers || {},
});
};
const tryError = (error: Error) => {
console.log('脚本错误--- :', error);
Sentry.captureException(error);
};
/** 全局错误处理
*
* @param {(Error | AxiosError)} error 错误信息
* @param {boolean} [isHttp=false] 在请求拦截中传 `true` 为了防止请求错误重复上报
* @return {*}
*/
export const _GlobalError = (error: any, isHttp = false) => {
if (!error) return;
if (isHttp && error.response) {
responseError(error as AxiosError);
} else {
tryError(error as Error);
}
};
请求错误
:::warning
请求错误上报,是在 axios
中的 请求拦截
和 响应拦截
中使用 _GlobalError
第二个参数需要传一个 true
:::
axios.ts
import axios from 'axios';
import { _GlobalError } from '../utils/error';
axios.interceptors.response.use(
() => {},
(error) => {
// code ...
_GlobalError(error, true);
},
);
axios.interceptors.request.use(
() => {},
(error) => {
// code ...
_GlobalError(error, true);
},
);
脚本错误
脚本错误上报,一般为自动上报,如果手动上报可以参考下面代码
onError() {
try {
const a: any = {};
const num = Math.floor(Math.random() * 10);
a.b[num].d.c = '1';
} catch (error) {
this.$utils._GlobalError(error); // _GlobalError 已经挂载到 Vue 实例上
}
}
::: tiptry/catch
里面的请求,如果报错,已经在 axios
中的拦截器中已经进行上报;
这里面的错误请求将被过滤掉;
:::
async onSendRequest() {
try {
const data = await this.$http.post<{data:{a:number}}>(this.$api.login, { a: 12 });
data.a.b.c = ''; // 抛出异常
} catch (error) {
this.$utils._GlobalError(error);
}
}
加载优化
使用方式 1
配置 .babelrc 使用按需加载
@shencom/plugins
内容
{
"plugins": [
[
"import",
{
"libraryName": "@shencom/plugins",
"libraryDirectory": "es",
"camel2DashComponentName": false
}
]
]
}
使用方式 2
import Sentry from '@shencom/plugins/es/sentry';
Sentry.install({
// ...
});