1.addEventListener
window.addEventListener('error', (error) => {
console.log('我知道 404 錯誤了');
console.log(
error
);
return true;
}, true);
2.onerror
throw new Error('拋出異常'); //拋出異常
window.onerror = function (msg, url, row, col, error) {
Access-Control-Allow-Origin:*
console.log('我知道錯誤了');
console.log({
msg, url, row, col, error
})
return true; // 注意,在返回 true 的時候,異常纔不會繼續向上拋出error;
};
//條件
//1.服務器設置Access-Control-Allow-Origin的響應頭
//2.<script crossorigin></script> 使得加載的跨域腳本可以得出跟同域腳本同樣的報錯信息
3. promise+unhandledrejection
new Promise(function(resolve, reject) {
reject(new Error('haha'))
})
/瀏覽器自帶unhandledrejection事件監聽全局沒有catch的Promise執行
window.addEventListener('unhandledrejection', function(err) {
console.log(err);
});
4.AST
var fs = require('fs');
var _ = require('lodash');
var UglifyJS = require('uglify-js');
var isASTFunctionNode = function (node) {
return node instanceof UglifyJS.AST_Defun || node instanceof UglifyJS.AST_Function;
}
var globalFuncTryCatch = function (inputCode, errorHandler) {
if(!_.isFunction(errorHandler)){
throw 'errorHandler should be a valid function';
}
var errorHandlerSource = errorHandler.toString();
var errorHandlerAST = UglifyJS.parse('(' + errorHandlerSource + ')(error);');
var tryCatchAST = UglifyJS.parse('try{}catch(error){}');
var inputAST = UglifyJS.parse(inputCode);
var topFuncScope = [];
//將錯誤處理函數包裹進入catch中
tryCatchAST.body[0].bcatch.body[0] = errorHandlerAST;
//蒐集所有函數
var walker = new UglifyJS.TreeWalker(function (node) {
if (isASTFunctionNode(node)) {
topFuncScope.push(node);
}
});
inputAST.walk(walker);
//對函數進行變換, 添加try catch語句
var transfer = new UglifyJS.TreeTransformer(null,
function (node) {
if (isASTFunctionNode(node) && _.includes(topFuncScope, node)) {
//函數內部代碼蒐集
var stream = UglifyJS.OutputStream();
for (var i = 0; i < node.body.length; i++) {
node.body[i].print(stream)
}
var innerFuncCode = stream.toString();
//清除try catch中定義的多餘語句
tryCatchAST.body[0].body.splice(0, tryCatchAST.body[0].body.length);
//用try catch包裹函數代碼
var innerTyrCatchNode = UglifyJS.parse(innerFuncCode, {toplevel: tryCatchAST.body[0]});
//獲取函數殼
node.body.splice(0, node.body.length);
//生成有try catch的函數
return UglifyJS.parse(innerTyrCatchNode.print_to_string(), {toplevel: node});
}
});
inputAST.transform(transfer);
var outputCode = inputAST.print_to_string({beautify: true});
return outputCode;
}
module.exports.globalFuncTryCatch = globalFuncTryCatch;