对各种异步回调都使用try catch错误上报


 
var moon_init = function () {
    // 前端的@cunjinli
    (function () {
        // @cunjinli 重写alert函数, moonsafe监控
        var _alert = window.alert;
        window.__alertList = [];
        window.alert = function (msg) {
            _alert(msg);
            window.__alertList.push(msg);
        };
    })();
    /**
     * moonsafe @cunjinli 加在这里
     */
    (function () {
        // if (window.__nonce_str) {
        //   var __old_createElement = document.createElement;
        //   document.createElement = function(tagName) {
        //     var node = __old_createElement.apply(this, arguments);
        //     if (typeof tagName == 'object') {
        //       tagName = tagName.toString();
        //     }
        //     if (typeof tagName == 'string' && tagName.toLowerCase() == 'script') {
        //       node.setAttribute("nonce", window.__nonce_str);
        //     }
        //     return node;
        //   }
        // }
        if (window.addEventListener && window.__DEBUGINFO && Math.random() < 0.01) {
            window.addEventListener("load", function () {
                var node = document.createElement('script');
                node.src = __DEBUGINFO.safe_js;
                node.type = 'text/javascript';
                node.async = true;
                var head = document.head || (document.getElementsByTagName("head")[0]);
                head.appendChild(node);
            });
        }
    })();
    /**
     * mooncatch
     * 对各种异步回调都使用try catch错误上报
     * @radeonwu raphealguo
     */
    (function () {
        var inWx = (/MicroMessenger/i).test(navigator.userAgent);
        var inMp = (/MPAPP/i).test(navigator.userAgent);
        var _idkey = 121261; //上报的idkey 添加默认上报值
        var _startKey; //开始的key
        var _limit; //上报的key的长度
        var _badjsId;
        var _reportOpt; //上报的额外信息
        var _extInfo; //附加的预留字段,如网络采样率采样率network_rate, 总体上报率rate
        var MOON_LISTENER_ERROR_KEY_OFFSET = 2; //addEventListener上报时的偏移量为2
        var MOON_AJAX_NETWORK_OFFSET = 4; //network错误时的上报偏移量为4,这里在ajax.js中上报,这里需要加入采样率
        var MOON_ASYNC_ERROR_KEY_OFFSET = 9; //setTimeout和setInterval上报时的偏移量为9
        var MOON_LOCALSTORAGE_ERROR_KEY_OFFSET = 10; //localstorage.setItem失败时的偏移量为10
        window.__initCatch = function (opt) {
            _idkey = opt.idkey;
            _startKey = opt.startKey || 0;
            _limit = opt.limit;
            _badjsId = opt.badjsId;
            _reportOpt = opt.reportOpt || "";
            _extInfo = opt.extInfo || {};
            _extInfo.rate = _extInfo.rate || 0.5;
        }
        //暴露的上报函数,供core.js和ajax.js上报错误使用,array = [{offset:MOON_JSAPI_KEY_OFFSET, log:"ready", e:e}]
        window.__moon_report = function (array, rate_opt) {
            var isAcrossOrigin = false;
            var href = '';
            try {
                href = top.location.href;
            } catch (e) {
                isAcrossOrigin = true;
            }
            var rate = 0.5;
            if (!!_extInfo && !!_extInfo.rate) {
                rate = _extInfo.rate;
            }
            if (!!rate_opt && (typeof rate_opt == 'number')) {
                rate = rate_opt;
            }
            if (
                (!(/mp\.weixin\.qq\.com/).test(location.href) && !(/payapp\.weixin\.qq\.com/).test(location.href)) ||
                Math.random() > rate ||
                !(inWx || inMp) ||
                (top != window && !isAcrossOrigin && !(/mp\.weixin\.qq\.com/).test(href))
            ) {
                //return ;
            }
            if (isObject(array))
                array = [array];
            if (!isArray(array) || _idkey == '')
                return;
            var data = "";
            var log = []; //存放array中每个对象关联的log
            var key = []; //存放array中每个上报的key
            var val = []; //存放array中每个上报的value
            var idkey = [];
            //如果这里没有opt.limit,直接上报到startKey
            if (typeof _limit != "number") {
                _limit = Infinity;
            }
            for (var i = 0; i < array.length; i++) {
                var item = array[i] || {};
                if (item.offset > _limit) continue; //上报的偏移量超过limit
                if (typeof item.offset != "number") continue;
                if (item.offset == MOON_AJAX_NETWORK_OFFSET && !!_extInfo && !!_extInfo.network_rate && Math.random() >= _extInfo.network_rate) {
                    continue;
                }
                //log[i] = item.log || "";
                var k = _limit == Infinity ? _startKey : (_startKey + item.offset);
                log[i] = (("[moon]" + _idkey + "_" + k + ";") + item.log + ";" + getErrorMessage(item.e || {})) || "";
                key[i] = k;
                val[i] = 1;
            }
            for (var j = 0; j < key.length; j++) {
                idkey[j] = _idkey + "_" + key[j] + "_" + val[j];
                data = data + "&log" + j + "=" + log[j];
            }
            if (idkey.length > 0) {
                // sendReport("idkey=" + idkey.join(";") + "&lc=" + log.length + data);
                sendReport("POST", location.protocol + '//mp.weixin.qq.com/mp/jsmonitor?', "idkey=" + idkey.join(";") + "&r=" + Math.random() + "&lc=" + log.length + data);
                // 把图文消息的错误上报一份到badjs,只支持get请求
                // 这里由于量比较大,把badjs的内层怼爆了,这里加多一个采样,并且去掉用户的信息
                var rate = 1;
                if (_extInfo && _extInfo.badjs_rate) { // 初始化时的badjs采样率
                    rate = _extInfo.badjs_rate;
                }
                if (Math.random() < rate) {
                    data = data.replace(/uin\:(.)*\|biz\:(.)*\|mid\:(.)*\|idx\:(.)*\|sn\:(.)*\|/, '');
                    if (!!_badjsId) {
                        var _img = new Image();
                        var _src = 'https://badjs.weixinbridge.com/badjs?id=' + _badjsId + '&level=4&from=' + encodeURIComponent(location.host) + '&msg=' + encodeURIComponent(data);
                        _img.src = _src.slice(0, 1024);
                    }
                    // badjs同时报一份到新监控 
                    if (typeof WX_BJ_REPORT != "undefined" && WX_BJ_REPORT.BadJs) {
                        for (var i = 0; i < array.length; i++) {
                            var item = array[i] || {};
                            if (item.e) {
                                WX_BJ_REPORT.BadJs.onError(item.e, { _info: item.log });
                            } else {
                                var name = /[^:;]*/.exec(item.log)[0];
                                WX_BJ_REPORT.BadJs.report(name, item.log, { mid: "mmbizwap:Monitor" });
                            }
                        }
                    }
                } else {
                    //虽然采样没有执行 但实际是有被BadJs.onError,置位一下
                    for (var i = 0; i < array.length; i++) {
                        var item = array[i] || {};
                        if (item.e) {
                            item.e.BADJS_EXCUTED = true;
                        }
                    }
                }
            }
        }
        function isArray(obj) { //判断输入是否为数组
            return Object.prototype.toString.call(obj) === '[object Array]';
        }
        function isObject(obj) { //判断输入是否为对象
            return Object.prototype.toString.call(obj) === '[object Object]';
        }
        function getErrorMessage(e) {
            var stack = e.stack + ' ' + e.toString() || ""; //错误堆栈信息
            try {
                //先取出res域名
                if (!window.testenv_reshost) {
                    stack = stack.replace(/http(s)?:\/\/res\.wx\.qq\.com/g, "");
                } else {
                    var host = 'http(s)?://' + window.testenv_reshost;
                    var reg = new RegExp(host, 'g');
                    stack = stack.replace(reg, "");
                }
                //提取最后一个.js前边的
                var reg = /\/([^.]+)\/js\/(\S+?)\.js(\,|:)?/g;
                while (reg.test(stack)) {
                    // stack = stack.replace(reg, "3"); 解决$问题
                    stack = stack.replace(reg, function (a, b, c, d, e, f) {
                        return c + d
                    });
                }
            } catch (e) {
                stack = e.stack ? e.stack : "" //错误堆栈信息
            }
            var ret = [];
            for (o in _reportOpt) {
                if (_reportOpt.hasOwnProperty(o)) {
                    ret.push(o + ":" + _reportOpt[o]);
                }
            }
            ret.push("STK:" + stack.replace(/\n/g, ""));
            return ret.join("|");
        }
        function sendReport(type, url, data) { //post方法用于提交数据
            if (!/^mp\.weixin\.qq\.com$/.test(location.hostname)) { //非MP域名使用 img方式上报
                var tmp = [];
                data = data.replace(location.href, (location.origin || "") + (location.pathname || "")).replace("#wechat_redirect", "").replace("#rd", "").split("&");
                for (var i = 0, il = data.length; i < il; i++) {
                    var a = data[i].split("=");
                    if (!!a[0] && !!a[1]) {
                        tmp.push(a[0] + "=" + encodeURIComponent(a[1]));
                    }
                }
                var _img = new window.Image();
                _img.src = (url + tmp.join("&")).substr(0, 1024);
                return;
            }
            var xmlobj; //定义XMLHttpRequest对象  
            if (window.ActiveXObject) { //如果当前浏览器支持Active Xobject,则创建ActiveXObject对象    
                try {
                    xmlobj = new ActiveXObject("Msxml2.XMLHTTP");
                } catch (e) {
                    try {
                        xmlobj = new ActiveXObject("Microsoft.XMLHTTP");
                    } catch (E) {
                        xmlobj = false;
                    }
                }
            } else if (window.XMLHttpRequest) { //如果当前浏览器支持XMLHttpRequest,则创建XMLHttpRequest对象  
                xmlobj = new XMLHttpRequest();
            }
            if (!xmlobj) return;
            //xmlobj.open("POST", location.protocol + "//mp.weixin.qq.com/mp/jsmonitor?", true);         
            xmlobj.open(type, url, true);
            xmlobj.setRequestHeader("cache-control", "no-cache");
            xmlobj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); //设置请求头信息              
            xmlobj.setRequestHeader("X-Requested-With", "XMLHttpRequest");
            xmlobj.send(data); //发送数据  
        }
        function catTimeout(foo) {
            return function (cb, timeout) {
                if (typeof cb === 'string') {
                    try {
                        cb = new Function(cb);
                    } catch (err) {
                        throw err;
                    }
                }
                var args = [].slice.call(arguments, 2);
                var _cb = cb;
                cb = function () {
                    try {
                        return _cb.apply(this, (args.length && args) || arguments);
                    } catch (error) {
                        if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑
                            console.error("[TryCatch]" + error.stack);
                        }
                        if (!!_idkey && !!window.__moon_report) { //没有初始化_key,直接throw error
                            //sendReport(error);
                            window.__moon_report([{ offset: MOON_ASYNC_ERROR_KEY_OFFSET, log: "timeout_error;host:" + location.host, e: error }]);
                            //breakOnError(timeoutkey);
                        }
                        throw error;
                    }
                }
                return foo(cb, timeout);
            };
        };
        window.setTimeout = catTimeout(window.setTimeout);
        window.setInterval = catTimeout(window.setInterval);
        if (Math.random() < 0.01 && !!window.Document && !!window.HTMLElement) {
            var cb_map = {};
            var moon_lid = 0;
            function catAddListener(foo) {
                return function (type, cb, useCapture) {
                    if (typeof useCapture === "undefined") {
                        var useCapture = false;
                    }
                    var that = this;
                    var _cb = cb || function () { };
                    cb = function () {
                        try {
                            //arguments[0].currentTarget.setAttribute("data-moon_lid") = moon_lid;
                            //_cb.moon_lid = moon_lid;
                            return _cb.apply(that, arguments);
                        } catch (error) {
                            if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑
                                console.error("[TryCatch]" + error.stack);
                            }
                            if (!!_idkey && !!window.__moon_report) { //没有初始化_key,直接throw error
                                window.__moon_report([{ offset: MOON_LISTENER_ERROR_KEY_OFFSET, log: "listener_error;type:" + type + ";host:" + location.host, e: error }]);
                                //breakOnError(timeoutkey);
                            }
                            throw error;
                        }
                    }
                    _cb.moon_lid = moon_lid;
                    cb_map[moon_lid] = cb;
                    moon_lid++;
                    return foo.call(that, type, cb, useCapture);
                }
            }
            function catRemoveListener(foo) {
                return function (type, cb, useCapture) {
                    if (typeof useCapture === "undefined") {
                        var useCapture = false;
                    }
                    var that = this;
                    cb = cb_map[cb.moon_lid];
                    return foo.call(that, type, cb, useCapture);
                }
            }
            Document.prototype.addEventListener = catAddListener(Document.prototype.addEventListener);
            Document.prototype.removeEventListener = catRemoveListener(Document.prototype.removeEventListener);
            HTMLElement.prototype.addEventListener = catAddListener(HTMLElement.prototype.addEventListener);
            HTMLElement.prototype.removeEventListener = catRemoveListener(HTMLElement.prototype.removeEventListener);
        }
        //alert("setItem begin");
        //window.localStorage.setItem = function(){a=c;}//故意
        var ua = window.navigator.userAgent;
        if ((/ip(hone|ad|od)/i.test(ua) || /android/i.test(ua)) && !/windows phone/i.test(ua) && !!window.localStorage && !!window.localStorage.setItem) {
            var _setItem = window.localStorage.setItem;
            var count = 0;
            window.localStorage.setItem = function (k, v) {
                if (count >= 10) { //一直失败 不要再继续试了,可能类似safari无痕模式 不允许写入了
                    return;
                }
                try {
                    _setItem.call(window.localStorage, k, v);
                } catch (error) {
                    //alert(error);
                    if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑
                        console.error("[TryCatch]" + error.stack);
                    }
                    window.__moon_report([{ offset: MOON_LOCALSTORAGE_ERROR_KEY_OFFSET, log: "localstorage_error;" + error.toString(), e: error }]);
                    count++;
                    if (count >= 3 && !!window.moon && window.moon.clear) {
                        // 可能爆满 清理一下localstorage
                        moon.clear();
                    }
                }
            }
            //alert("setItem end");
        }
    })();
    // 后面的@cunjinli
};
moon_init();
  //由于moon异步化,所以有些逻辑需要moon加载完之后才执行的 放到全局callback函数__moon_initcallback里边

  view-source:https://mp.weixin.qq.com/s/_xsb_91-eQAq10IyDa2tvQ

var moon_init = function () {     // 前端的@cunjinli     (function () {         // @cunjinli 重写alert函数, moonsafe监控         var _alert = window.alert;         window.__alertList = [];         window.alert = function (msg) {             _alert(msg);             window.__alertList.push(msg);         };     })();     /**      * moonsafe @cunjinli 加在这里      */     (function () {         // if (window.__nonce_str) {         //   var __old_createElement = document.createElement;         //   document.createElement = function(tagName) {         //     var node = __old_createElement.apply(this, arguments);         //     if (typeof tagName == 'object') {         //       tagName = tagName.toString();         //     }         //     if (typeof tagName == 'string' && tagName.toLowerCase() == 'script') {         //       node.setAttribute("nonce", window.__nonce_str);         //     }         //     return node;         //   }         // }         if (window.addEventListener && window.__DEBUGINFO && Math.random() < 0.01) {             window.addEventListener("load", function () {                 var node = document.createElement('script');                 node.src = __DEBUGINFO.safe_js;                 node.type = 'text/javascript';                 node.async = true;                 var head = document.head || (document.getElementsByTagName("head")[0]);                 head.appendChild(node);             });         }     })();     /**      * mooncatch      * 对各种异步回调都使用try catch错误上报      * @radeonwu raphealguo      */     (function () {         var inWx = (/MicroMessenger/i).test(navigator.userAgent);         var inMp = (/MPAPP/i).test(navigator.userAgent);         var _idkey = 121261; //上报的idkey 添加默认上报值         var _startKey; //开始的key         var _limit; //上报的key的长度         var _badjsId;         var _reportOpt; //上报的额外信息         var _extInfo; //附加的预留字段,如网络采样率采样率network_rate, 总体上报率rate         var MOON_LISTENER_ERROR_KEY_OFFSET = 2; //addEventListener上报时的偏移量为2         var MOON_AJAX_NETWORK_OFFSET = 4; //network错误时的上报偏移量为4,这里在ajax.js中上报,这里需要加入采样率         var MOON_ASYNC_ERROR_KEY_OFFSET = 9; //setTimeout和setInterval上报时的偏移量为9         var MOON_LOCALSTORAGE_ERROR_KEY_OFFSET = 10; //localstorage.setItem失败时的偏移量为10         window.__initCatch = function (opt) {             _idkey = opt.idkey;             _startKey = opt.startKey || 0;             _limit = opt.limit;             _badjsId = opt.badjsId;             _reportOpt = opt.reportOpt || "";             _extInfo = opt.extInfo || {};             _extInfo.rate = _extInfo.rate || 0.5;         }         //暴露的上报函数,供core.js和ajax.js上报错误使用,array = [{offset:MOON_JSAPI_KEY_OFFSET, log:"ready", e:e}]         window.__moon_report = function (array, rate_opt) {             var isAcrossOrigin = false;             var href = '';             try {                 href = top.location.href;             } catch (e) {                 isAcrossOrigin = true;             }             var rate = 0.5;             if (!!_extInfo && !!_extInfo.rate) {                 rate = _extInfo.rate;             }             if (!!rate_opt && (typeof rate_opt == 'number')) {                 rate = rate_opt;             }             if (                 (!(/mp\.weixin\.qq\.com/).test(location.href) && !(/payapp\.weixin\.qq\.com/).test(location.href)) ||                 Math.random() > rate ||                 !(inWx || inMp) ||                 (top != window && !isAcrossOrigin && !(/mp\.weixin\.qq\.com/).test(href))             ) {                 //return ;             }             if (isObject(array))                 array = [array];             if (!isArray(array) || _idkey == '')                 return;             var data = "";             var log = []; //存放array中每个对象关联的log             var key = []; //存放array中每个上报的key             var val = []; //存放array中每个上报的value             var idkey = [];             //如果这里没有opt.limit,直接上报到startKey             if (typeof _limit != "number") {                 _limit = Infinity;             }             for (var i = 0; i < array.length; i++) {                 var item = array[i] || {};                 if (item.offset > _limit) continue; //上报的偏移量超过limit                 if (typeof item.offset != "number") continue;                 if (item.offset == MOON_AJAX_NETWORK_OFFSET && !!_extInfo && !!_extInfo.network_rate && Math.random() >= _extInfo.network_rate) {                     continue;                 }                 //log[i] = item.log || "";                 var k = _limit == Infinity ? _startKey : (_startKey + item.offset);                 log[i] = (("[moon]" + _idkey + "_" + k + ";") + item.log + ";" + getErrorMessage(item.e || {})) || "";                 key[i] = k;                 val[i] = 1;             }             for (var j = 0; j < key.length; j++) {                 idkey[j] = _idkey + "_" + key[j] + "_" + val[j];                 data = data + "&log" + j + "=" + log[j];             }             if (idkey.length > 0) {                 // sendReport("idkey=" + idkey.join(";") + "&lc=" + log.length + data);                 sendReport("POST", location.protocol + '//mp.weixin.qq.com/mp/jsmonitor?', "idkey=" + idkey.join(";") + "&r=" + Math.random() + "&lc=" + log.length + data);                 // 把图文消息的错误上报一份到badjs,只支持get请求                 // 这里由于量比较大,把badjs的内层怼爆了,这里加多一个采样,并且去掉用户的信息                 var rate = 1;                 if (_extInfo && _extInfo.badjs_rate) { // 初始化时的badjs采样率                     rate = _extInfo.badjs_rate;                 }                 if (Math.random() < rate) {                     data = data.replace(/uin\:(.)*\|biz\:(.)*\|mid\:(.)*\|idx\:(.)*\|sn\:(.)*\|/, '');                     if (!!_badjsId) {                         var _img = new Image();                         var _src = 'https://badjs.weixinbridge.com/badjs?id=' + _badjsId + '&level=4&from=' + encodeURIComponent(location.host) + '&msg=' + encodeURIComponent(data);                         _img.src = _src.slice(0, 1024);                     }                     // badjs同时报一份到新监控                     if (typeof WX_BJ_REPORT != "undefined" && WX_BJ_REPORT.BadJs) {                         for (var i = 0; i < array.length; i++) {                             var item = array[i] || {};                             if (item.e) {                                 WX_BJ_REPORT.BadJs.onError(item.e, { _info: item.log });                             } else {                                 var name = /[^:;]*/.exec(item.log)[0];                                 WX_BJ_REPORT.BadJs.report(name, item.log, { mid: "mmbizwap:Monitor" });                             }                         }                     }                 } else {                     //虽然采样没有执行 但实际是有被BadJs.onError,置位一下                     for (var i = 0; i < array.length; i++) {                         var item = array[i] || {};                         if (item.e) {                             item.e.BADJS_EXCUTED = true;                         }                     }                 }             }         }         function isArray(obj) { //判断输入是否为数组             return Object.prototype.toString.call(obj) === '[object Array]';         }         function isObject(obj) { //判断输入是否为对象             return Object.prototype.toString.call(obj) === '[object Object]';         }         function getErrorMessage(e) {             var stack = e.stack + ' ' + e.toString() || ""; //错误堆栈信息             try {                 //先取出res域名                 if (!window.testenv_reshost) {                     stack = stack.replace(/http(s)?:\/\/res\.wx\.qq\.com/g, "");                 } else {                     var host = 'http(s)?://' + window.testenv_reshost;                     var reg = new RegExp(host, 'g');                     stack = stack.replace(reg, "");                 }                 //提取最后一个.js前边的                 var reg = /\/([^.]+)\/js\/(\S+?)\.js(\,|:)?/g;                 while (reg.test(stack)) {                     // stack = stack.replace(reg, "3"); 解决$问题                     stack = stack.replace(reg, function (a, b, c, d, e, f) {                         return c + d                     });                 }             } catch (e) {                 stack = e.stack ? e.stack : "" //错误堆栈信息             }             var ret = [];             for (o in _reportOpt) {                 if (_reportOpt.hasOwnProperty(o)) {                     ret.push(o + ":" + _reportOpt[o]);                 }             }             ret.push("STK:" + stack.replace(/\n/g, ""));             return ret.join("|");         }         function sendReport(type, url, data) { //post方法用于提交数据             if (!/^mp\.weixin\.qq\.com$/.test(location.hostname)) { //非MP域名使用 img方式上报                 var tmp = [];                 data = data.replace(location.href, (location.origin || "") + (location.pathname || "")).replace("#wechat_redirect", "").replace("#rd", "").split("&");                 for (var i = 0, il = data.length; i < il; i++) {                     var a = data[i].split("=");                     if (!!a[0] && !!a[1]) {                         tmp.push(a[0] + "=" + encodeURIComponent(a[1]));                     }                 }                 var _img = new window.Image();                 _img.src = (url + tmp.join("&")).substr(0, 1024);                 return;             }             var xmlobj; //定义XMLHttpRequest对象               if (window.ActiveXObject) { //如果当前浏览器支持Active Xobject,则创建ActiveXObject对象                     try {                     xmlobj = new ActiveXObject("Msxml2.XMLHTTP");                 } catch (e) {                     try {                         xmlobj = new ActiveXObject("Microsoft.XMLHTTP");                     } catch (E) {                         xmlobj = false;                     }                 }             } else if (window.XMLHttpRequest) { //如果当前浏览器支持XMLHttpRequest,则创建XMLHttpRequest对象                   xmlobj = new XMLHttpRequest();             }             if (!xmlobj) return;             //xmlobj.open("POST", location.protocol + "//mp.weixin.qq.com/mp/jsmonitor?", true);                     xmlobj.open(type, url, true);             xmlobj.setRequestHeader("cache-control", "no-cache");             xmlobj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); //设置请求头信息                           xmlobj.setRequestHeader("X-Requested-With", "XMLHttpRequest");             xmlobj.send(data); //发送数据           }         function catTimeout(foo) {             return function (cb, timeout) {                 if (typeof cb === 'string') {                     try {                         cb = new Function(cb);                     } catch (err) {                         throw err;                     }                 }                 var args = [].slice.call(arguments, 2);                 var _cb = cb;                 cb = function () {                     try {                         return _cb.apply(this, (args.length && args) || arguments);                     } catch (error) {                         if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑                             console.error("[TryCatch]" + error.stack);                         }                         if (!!_idkey && !!window.__moon_report) { //没有初始化_key,直接throw error                             //sendReport(error);                             window.__moon_report([{ offset: MOON_ASYNC_ERROR_KEY_OFFSET, log: "timeout_error;host:" + location.host, e: error }]);                             //breakOnError(timeoutkey);                         }                         throw error;                     }                 }                 return foo(cb, timeout);             };         };         window.setTimeout = catTimeout(window.setTimeout);         window.setInterval = catTimeout(window.setInterval);         if (Math.random() < 0.01 && !!window.Document && !!window.HTMLElement) {             var cb_map = {};             var moon_lid = 0;             function catAddListener(foo) {                 return function (type, cb, useCapture) {                     if (typeof useCapture === "undefined") {                         var useCapture = false;                     }                     var that = this;                     var _cb = cb || function () { };                     cb = function () {                         try {                             //arguments[0].currentTarget.setAttribute("data-moon_lid") = moon_lid;                             //_cb.moon_lid = moon_lid;                             return _cb.apply(that, arguments);                         } catch (error) {                             if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑                                 console.error("[TryCatch]" + error.stack);                             }                             if (!!_idkey && !!window.__moon_report) { //没有初始化_key,直接throw error                                 window.__moon_report([{ offset: MOON_LISTENER_ERROR_KEY_OFFSET, log: "listener_error;type:" + type + ";host:" + location.host, e: error }]);                                 //breakOnError(timeoutkey);                             }                             throw error;                         }                     }                     _cb.moon_lid = moon_lid;                     cb_map[moon_lid] = cb;                     moon_lid++;                     return foo.call(that, type, cb, useCapture);                 }             }             function catRemoveListener(foo) {                 return function (type, cb, useCapture) {                     if (typeof useCapture === "undefined") {                         var useCapture = false;                     }                     var that = this;                     cb = cb_map[cb.moon_lid];                     return foo.call(that, type, cb, useCapture);                 }             }             Document.prototype.addEventListener = catAddListener(Document.prototype.addEventListener);             Document.prototype.removeEventListener = catRemoveListener(Document.prototype.removeEventListener);             HTMLElement.prototype.addEventListener = catAddListener(HTMLElement.prototype.addEventListener);             HTMLElement.prototype.removeEventListener = catRemoveListener(HTMLElement.prototype.removeEventListener);         }         //alert("setItem begin");         //window.localStorage.setItem = function(){a=c;}//故意         var ua = window.navigator.userAgent;         if ((/ip(hone|ad|od)/i.test(ua) || /android/i.test(ua)) && !/windows phone/i.test(ua) && !!window.localStorage && !!window.localStorage.setItem) {             var _setItem = window.localStorage.setItem;             var count = 0;             window.localStorage.setItem = function (k, v) {                 if (count >= 10) { //一直失败 不要再继续试了,可能类似safari无痕模式 不允许写入了                     return;                 }                 try {                     _setItem.call(window.localStorage, k, v);                 } catch (error) {                     //alert(error);                     if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑                         console.error("[TryCatch]" + error.stack);                     }                     window.__moon_report([{ offset: MOON_LOCALSTORAGE_ERROR_KEY_OFFSET, log: "localstorage_error;" + error.toString(), e: error }]);                     count++;                     if (count >= 3 && !!window.moon && window.moon.clear) {                         // 可能爆满 清理一下localstorage                         moon.clear();                     }                 }             }             //alert("setItem end");         }     })();     // 后面的@cunjinli }; moon_init();   //由于moon异步化,所以有些逻辑需要moon加载完之后才执行的 放到全局callback函数__moon_initcallback里边

搜索

复制

相关