js捕獲錯誤信息

這個不是很常用的功能, 但是想收集客戶端的錯誤信息時卻很有必要了解下。

捕獲分為兩個方面:

1、收集JS語法、執(zhí)行錯誤

最初的是想直接獲取控制臺的錯誤信息; 然而這并不大可行,JS并沒有這樣的功能。

轉(zhuǎn)換下思路:在錯誤發(fā)生時,將錯誤進行存儲。

原生JS實現(xiàn)方式:

通過重載 window 對象下的 onerror 函數(shù), 可以截取到這些信息。

window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) {
       console.log("錯誤信息:" , errorMessage);
       console.log("出錯文件:" , scriptURI);
       console.log("出錯行號:" , lineNumber);
       console.log("出錯列號:" , columnNumber);
       console.log("錯誤詳情:" , errorObj);
    }

框架實現(xiàn)方式:

然而在部分框下這種方式是不生效的,原因是在框架解析代碼前,所有的代碼可以理解為都是文本而非js文件。

只在angular 下做了實現(xiàn), 沒有實現(xiàn)過的框架沒有發(fā)言權(quán);接下來將以angular為例。

angular 環(huán)境下無法使用window.ondrror. 原因是angular體制內(nèi)的代碼通過$even 解析后并不會將錯誤移交給 window.onerror 函數(shù)

但是 angular 在解析時會將所有的語法、執(zhí)行錯誤時將會觸發(fā) $ExceptionHandlerProvider 函數(shù):

function $ExceptionHandlerProvider() {
  this.$get = ['$log', function($log) {
    return function(exception, cause) {
      $log.error.apply($log, arguments);
    };
  }];
}

$ExceptionHandlerProvider 函數(shù)將會調(diào)用 consoleLog('error') 函數(shù)

this.$get = ['$window', function($window) {
return {
  /**
   * @ngdoc method
   * @name $log#log
   *
   * @description
   * Write a log message
   */
  log: consoleLog('log'),
  /**
   * @ngdoc method
   * @name $log#info
   *
   * @description
   * Write an information message
   */
  info: consoleLog('info'),
  /**
   * @ngdoc method
   * @name $log#warn
   *
   * @description
   * Write a warning message
   */
  warn: consoleLog('warn'),
  /**
   * @ngdoc method
   * @name $log#error
   *
   * @description
   * Write an error message
   */
  error: consoleLog('error'),
  /**
   * @ngdoc method
   * @name $log#debug
   *
   * @description
   * Write a debug message
   */
  debug: (function() {
    var fn = consoleLog('debug');
    return function() {
      if (debug) {
        fn.apply(self, arguments);
      }
    };
  }())
};
function consoleLog(type) {
  var console = $window.console || {},
      logFn = console[type] || console.log || noop,
      hasApply = false;
  // Note: reading logFn.apply throws an error in IE11 in IE8 document mode.
  // The reason behind this is that console.log has type "object" in IE8...
  try {
    hasApply = !!logFn.apply;
  } catch (e) {}
  if (hasApply) {
    return function() {
      var args = [];
      forEach(arguments, function(arg) {
        args.push(formatError(arg));
      });
      return logFn.apply(console, args);
    };
  }
  // we are IE which either doesn't have window.console => this is noop and we do nothing,
  // or we are IE where console.log doesn't have apply so we log at least first 2 args
  return function(arg1, arg2) {
    logFn(arg1, arg2 == null ? '' : arg2);
  };
}

最終這些錯誤會流入原生console.error內(nèi), 所以在angular下捕獲這些錯誤將變的異常簡單。僅僅需要重置console.error方法,如下所示:

resetConsole() {
    window.console._error = window.console.error;
    window.console.error = info => {
        // 在這里執(zhí)行錯誤存儲或發(fā)送
        window.console._error(info);
    };
}

angular 在解析錯誤時, 會通過$log.error.apply $window.console.error方法. 所以在這里將 console.error 進行重置后, 語法、執(zhí)行錯誤也會一并收集到。

2、收集請求錯誤

各框架都會將 XMLHttpRequest 進行封裝, 可以找到對應(yīng)的errror函數(shù)內(nèi)將錯誤進行捕獲。

原生實現(xiàn)收集請求錯前, 需要先對XMLHttpRequest進行封裝,示例如下:

ar ajax = function(type, url, callback){
    var xhr = new XMLHttpRequest();
    xhr.open(type, url);
    xhr.onreadystatechange = function() {
        if (xhr.readyState !== 4) {
            return;
        }
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
            callback();
        } else {
            console.log('收集到一條錯誤');// 在這里收集錯誤信息
        }
    };
    xhr.send(null);
}
// 因為.ccccccom這個路徑是不存在的, 所以會執(zhí)行收集區(qū)域的代碼。
ajax('GET', 'http://www.lovejavascript.ccccccom', function(a){console.log(a)});

如果對 XMLHttpRequest 封裝感興趣, 可以看下我寫的 jToo l類庫中的 ajax 對象。

作者:@拭目以待表格管理開源項目

Want to know How To Make Love?I know HTML!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容