随着公司业务的发展,前端项目也越来越多。有的时候客户反馈的一个问题,需要耗费大量的时间去查。错误信息不能第一时间获取,多少会给公司带来损失。这个时候我们就需要一套错误收集机制,去提前发现代码中存在的问题,在客户反馈之前把问题提前处理掉。或者在收到客户反馈的时候可以查到对应的错误栈来帮助我们快速去定位以及解决问题。下面主要介绍vue和微信小程序错误收集的方法。
错误收集方法
Vue错误收集
Vue提供了一个全局配置errorHandler,用于收集Vue运行时发生的错误。 详细介绍api?cn.vuejs.org/v2/api/#err…
用法:
Vue.config.errorHandler = function (err,vm,info) {
}
复制代码
当然拿到vue对应的实例之后,我们就可以轻松获取到vue对应的组件名称以及自定义属性等等(此处可自由发挥)。
以下是获取组件名称的方法:(来源:fundebug)
function formatComponentName(vm) {
if (vm.$root === vm) return 'root';
var name = vm._isVue
? (vm.$options && vm.$options.name) ||
(vm.$options && vm.$options._componentTag)
: vm.name;
return (
(name ? 'component <' + name + '>' : 'anonymous component') +
(vm._isVue && vm.$options && vm.$options.__file
? ' at ' + (vm.$options && vm.$options.__file)
: '')
);
}
复制代码
这个时候我们代码就可以改写成这样:
debug.js
let debugConfig = {
Vue: null,
entryName: 'entryName',136);">//脚本版本
scriptVersion: '1.0',136);">// 环境
releaseStage: 'pro'
},debug = {
notifyWarn({ message,metaData }) {
let type = 'caught',severity = 'warn';
_logReport({ type,severity,message,metaData });
},notifyError({ let severity = 'error';
_logReport({ // 日志上报
_logReport({ let { silentDev,Vue } = debugConfig;
message = message || error && error.message || '';
let { entryName,releaseStage,scriptVersion } = debugConfig,name = error && error.name || 'error',stacktrace = error && error.stack || '',time = Date.now(),title = document.title,url = window.location.href,client = {
userAgent: window.navigator.userAgent,height: window.screen.height,width: window.screen.width,referrer: window.document.referrer
},pageLevel = 'p4';
pageLevel = 'p0';
Vue.http.post(logReportUrl,{
entryName,scriptVersion,name,stacktrace,time,title,//页面等级
});
}
export default function(Vue,option = {}){
debugConfig = Object.assign(debugConfig,{ Vue,...option });
formatComponentName(vm) {
'root';
let name = vm._isVue
? (vm.$options && vm.$options.name) ||
(vm.$options && vm.$options._componentTag)
: vm.name;
return (
(name ? 'anonymous component') +
(vm._isVue && vm.$options && vm.$options.__file
? ' at ' + (vm.$options && vm.$options.__file)
: '')
);
}
Vue.config.errorHandler = function(err,info) {
if (vm) {
let componentName = formatComponentName(vm);
let propsData = vm.$options && vm.$options.propsData;
debug.notifyError({
error: err,metaData: {
componentName,propsData,info,userToken: { userId: 1 }
}
});
} else {
debug.notifyError({
error: err,metaData: {
userToken: { userId: //metaData可以存一些额外数据,比如:用户信息等
}
});
}
};
window.onerror = function(msg,lineNo,columnNo,error) {
debug.notifyError({
type: 'uncaught',metaData: {
userToken: { userId: //metaData可以存一些额外数据,比如:用户信息等
},message: msg,lineNumber: lineNo,columnNumber: columnNo,fileName: url
});
}
}
export { debug }
复制代码
当然你还可以捕获Promise、网络请求、图片等异常。此处推荐一篇比较全的文章,大家可自行去查看?juejin.im/post/5bd2db…
初始化:
import debug from './debug';
Vue.use(ngmmdebug,{ entryName: 'webmall' });
复制代码
如果你想自己上报错误可以通过:
;
debug.notifyError({ messag: '发生错误了' });
复制代码
微信小程序错误收集
微信小程序收集错误信息也是比较方便的,只需要在调用App函数时传入的对象中实现onError方法即可。文档地址:?developers.weixin.qq.com/miniprogram…
用法:
App({
onError (msg) {
console.log(msg);
}
})
复制代码
如果你想让代码移植性更高一点可以通过这样做:
debug.js
;
for (let key in options) {
params += '&' + key + '=' + options[key];
}
return params.substring(1);
}
// 将App暂存起来
let _App = App;
App = //config
let debugConfig = {
entryName: releaseStage: 'pro',scriptVersion: client: {}
}
wx.getSystemInfo({
success: function (res) {
debugConfig.client = res;
}
});
getPostData(error = '') {
let {
entryName,client
} = debugConfig,curPage = getCurrentPages()[getCurrentPages().length - 1],url = "postData",metaData = {},0);">'p0';
if (curPage) {
url = curPage.route;
pageLevel = 'p0';
urlParams = objToParam(curPage.options);
if (urlParams) {
url += '?' + urlParams;
}
}
name = error.split('n')[0] || 'error';
metaData = {
userToken: getHeaders()
}
try {
postData = {
data: JSON.stringify({
entryName,type: stacktrace: error,time: catch (e) {
console.error(e);
}
return postData;
}
_logReport(error) {
wx.request({
header: {
'content-type': 'application/x-www-form-urlencoded'
},method: 'POST',url: logReportUrl,data: getPostData(error)
});
}
let debug = {
init(option = {}) {
debugConfig = Object.assign({},debugConfig,option);
},notifyError(error) {
_logReport(error)
}
}
module.exports = debug;
复制代码
修改app.js:
;
ngmmdebug.init({
entryName: 'mall-wxapp',0);">'2.6.3'
})
复制代码
手动上报错误
;
ngmmdebug.notifyError('发生错误了~');
复制代码
小程序有几个比较特别的点可以看一下:
1、通过?wx.getSystemInfo
?获取设备信息,当然你还可以通过?wx.getUserInfo
?获取用户信息等。
2、小程序完整的链接需要通过页面options属性自行组装。
参考
收集字段参考
{
"entryName":"项目名称",0);">"scriptVersion""1.0",//脚本版本
"message""aler is not defined",96);">//错误描述
"metaData":{//自定义字段
"componentName""anonymous component at /Users/taoxinhua/git/webmall/src/components/app.vue",96);">//组件名称
"info""created hook",96);">//vue报错信息
"userToken"//用户登录信息
"user_id": 1
}
},0);">"name""ReferenceError",96);">//错误名称
"releaseStage""local",96);">//报错环境pre|beta|local
"stacktrace""ReferenceError: aler is not defined
at VueComponent.created (webpack-internal:///370:32:9)
at callHook (webpack-internal:///1:2666:21)
at VueComponent.Vue._init (webpack-internal:///1:4227:5)
at new VueComponent (webpack-internal:///1:4397:12)
at createComponentInstanceForVnode (webpack-internal:///1:3679:10)
at init (webpack-internal:///1:3496:45)
at createComponent (webpack-internal:///1:5148:9)
at createElm (webpack-internal:///1:5091:9)
at Vue$3.patch [as __patch__] (webpack-internal:///1:5607:9)
at Vue$3.Vue._update (webpack-internal:///1:2415:19)",96);">//错误栈
"time":1544437068009,96);">//发生错误时的客户端时间
"title""年糕妈妈优选",96);">//页面标题
"type""caught",96);">//错误类型参考fundebug
"url""http://localhost:3200/test",96);">//页面地址
"client"//客户端信息
"userAgent""Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/70.0.3538.110 Safari/537.36",0);">"height"800,0);">"width"1280,0);">"referrer""http://localhost:3200/test"
},0);">"pageLevel""p4"//页面错误级别,方便查询和优先处理重要页面的bug
}
复制代码