window.onerror全局异常捕获
window.onerror = function (msg, url, line){
// 可以捕获异步函数中的错误信息并进行处理,提示Script error.
console.log(msg); // 获取错误信息
console.log(url); // 获取出错的文件路径
console.log(line); // 获取错误出错的行数
};
setTimeout(function() {
console.log(obj); // 可以被捕获到,并在onerror中处理
}, 200);
try-catch运行时解决方案
try{
// 单一作用域try...catch可以捕获错误信息并进行处理
console.log(obj);
}catch(e){
console.log(e); //处理异常,ReferenceError: obj is not defined
}
try{
// 不同作用域不能捕获到错误信息
setTimeout(function() {
console.log(obj); // 直接报错,不经过catch处理
}, 200);
}catch(e){
console.log(e);
}
// 同一个作用域下能捕获到错误信息
setTimeout(function() {
try{
// 当前作用域try...catch可以捕获错误信息并进行处理
console.log(obj);
}catch(e){
console.log(e); //处理异常,ReferenceError: obj is not defined
}
}, 200);
ES6 Class的异常捕获方案
/**
* 封装React方法的错误处理,改成使用入参的prototype中是否有render生命周期函数来判断
* @param {object} Component 传入组件
* @return {object} 返回包裹后的组件
*/
function _defineReact(Component) {
var proto = Component.prototype;
var key;
// 封装本身constructor中的构造方法,React组件编译为ES5后是一个构造函数,ES6下面为class
if (_isTrueFunction(Component)) {
Component = wrapFunction(Component);
}
var componnetKeys = Object.getOwnPropertyNames(proto);
// 支持ES6类的属性方法错误捕获
for (var i = 0, len = componnetKeys.length; i < len; i++) {
key = componnetKeys[i];
proto[key] = wrapFunction(proto[key])
}
// 支持ES5下的属性方法错误捕获
for (key in proto) {
if (typeof proto[key] === 'function') {
proto[key] = wrapFunction(proto[key]);
}
}
return Component;
}
/**
* 判断是否为真实的函数,而不是class
* @param {Function} fn [description]
* @return {Boolean} [description]
*/
function _isTrueFunction(fn) {
var isTrueFunction = false;
try {
isTrueFunction = fn.prototype.constructor.arguments === null;
} catch (e) {
isTrueFunction = false;
}
for (var key in fn.prototype) {
return false;
}
return isTrueFunction;
}
class component extends React.Component {
componentDidMount(){
var a = {};
console.log(a.b.c);
}
render() {
return <div>hello world</div>;
}
}
export default _defineReact(component);
Promise内的错误捕获
// 如果浏览支持Promise,捕获promise里面then的报错,因为promise里面的错误onerror和try-catch都无法捕获
if (Promise && Promise.prototype.then) {
var promiseThen = Promise.prototype.then;
Promise.prototype.then = function(resolve, reject) {
return promiseThen.call(this, _wrapPromiseFunction(resolve), _wrapPromiseFunction(reject));
}
}
/**
* 输入一个函数,将函数内代码包裹进try-catch执行,then的resolve、reject和普通函数不一样
*
* @param {any} fn
* @returns 一个新的函数
*/
function _wrapPromiseFunction(fn) {
// 如果fn是个函数,则直接放到try-catch中运行,否则要将类的方法包裹起来,promise中的fn要返回null,不能返回空函数
if (typeof fn !== 'function') {
return null;
}
return function () {
try {
return fn.apply(this, arguments);
} catch (e) {
_errorProcess(e);
throw e;
}
};
}
评论 (0)