制作无错误的h5网页(代码记录)

jsError.js


import {LOG_LEVEL, errorReport} from './logger';
import {extend, isFunction, noop} from './utils';

/**
 * 错误信息捕获
 * @param {string} msg 错误信息
 * @param {string} url 出错的文件
 * @param {number} line 出错代码的行号
 * @param {number} col 出错代码的列号
 * @param {Object} error 错误的详细信息
 */
function onError(msg, url, line, col, error) {
  setTimeout(function () {
    let time = new Date().getTime();
    col = col || (window.event && window.event.errorCharacter) || 0;

    let msgString = msg.toLowerCase();
    let subString = 'script error';
    if (msgString.indexOf(subString) > -1) {
      msg = 'Script Error: See Browser Console for Detail----->' + msg;
    }

    let detail = {
      file: url,
      line: line,
      col: col,
      time: time,
      error: JSON.stringify(error)
    };
    if (!!error && !!error.stack) {
      // 如果浏览器有堆栈信息,直接使用
      detail.stack = error.stack.toString();
    } else if (onError.callee) {
      // 尝试通过callee拿堆栈信息
      let ext = [];
      let fn = onError.callee.caller;
      let c = 3;
      while (fn && (--c > 0)) {
        ext.push(fn.toString());
        if (fn === fn.caller) {
          break;
        }
        fn = fn.caller;
      }
      ext = ext.join(',');
      detail.stack = ext;
    }
    if (window.history && window.history.state) {
      detail.state = window.history.state;
    }

    let data = {
      msg: msg,
      url: document.location.href,
      detail: detail
    };

    errorReport(data, 'js_error');
  }, 0);
  return false;
}

window.console = window.console || {};
var _consoleError = console.error && isFunction(console.error) ? console.error : noop;

console.error = function (errMsg) {
  let errorArr = [];
  let errorObj = {
    msg: ''
  };
  for (let i = 0; i < arguments.length; i++) {
    let arg = arguments[i];
    if (typeof arg == 'object') {
      errorObj = extend(errorObj, arg);
    } else {
      errorArr.push(arg);
    }
  }
  errorArr.unshift(errorObj.msg);
  let errorMsg = errorArr.join(' ');

  errorObj.msg = errorMsg;
  errorReport(errorObj, 'js_error', LOG_LEVEL.ERROR);

  if (_consoleError && isFunction(_consoleError)) {
    _consoleError.apply(console, arguments);
  }
};
window.onerror = onError;

window.addEventListener('unhandledrejection', function (event) {
  let url, line, col;
  event.reason.stack.replace(/\((.+?):(\d+):(\d+)\)/, function (m, p1, p2, p3) {
    url = p1;
    line = p2;
    col = p3;
  });
  onError(event.reason.message, url, line, col, event.reason.stack);
});

  

logger.js

import {extend, isFunction} from './utils';
import {trimURL} from './utils/URLUtils';
import {hasExternal, doExternal} from './external/call';
import {remoteLog} from './external';

// 日志等级
export const LOG_LEVEL = {
  EMERG: 0,
  ALERT: 1,

  CRIT: 2,
  ERROR: 3,
  WARNING: 4,
  NOTICE: 5,
  INFO: 6,
  DEBUG: 7
};
const LOG_BASE_URL = '//log.17zuoye.cn';
// const ERROR_REPORT_URL = document.location.protocol + '//' + document.domain;
const ERROR_REPORT_URL = LOG_BASE_URL;

function getCookie(name, defaultValue) {
  let strCookie = document.cookie;
  let arrCookie = strCookie.split('; ');
  for (let i = 0; i < arrCookie.length; i++) {
    let arr = arrCookie[i].split('=');
    if (arr[0] == name) return arr[1];
  }
  return defaultValue;
}

/**
 * 生成日志信息
 * @param {object} logData
 * @returns {*}
 */
function buildLogInfo(logData) {
  logData = logData || {};
  let userId = getCookie('uid', '');
  let appInfo = window.appInfo || {};
  let pathName = window.location.pathname;
  let pathArr = pathName.split('/');
  let appName = appInfo.appName || logData.app || pathArr[1] || '';
  let subject = appInfo.subject || '';
  subject = subject.toUpperCase();
  let env = appInfo.env || '';
  userId = appInfo.userId || userId || '';

  let commonLogInfo = {
    user_agent: window.navigator.userAgent,
    school_type: 'junior',
    html_version: '',
    url: document.location.href || '',
    target: pathName || '',
    app: appName,
    userid: userId,
    subject: subject,
    env: env,
    error_code: '',
    error_type: '',
    detail: '',
    msg: '',
    data_type: ''
  };
  // etc,s0~s4处理
  let etc = logData.etc || {};
  delete logData.etc;
  for (let key in logData) {
    if (!logData.hasOwnProperty(key)) {
      continue;
    }
    if ((key in commonLogInfo) || ['s0', 's1', 's2', 's3', 's4'].indexOf(key) > -1) {
      commonLogInfo[key] = logData[key];
    } else {
      etc[key] = logData[key];
    }
  }
  let logObj = extend(commonLogInfo, {etc: JSON.stringify(etc)});
  return logObj;
}

/**
 * 打点
 * @param {string} module
 * @param {string} op
 * @param {Object} logData
 * @param {Function|null}callback
 * sendLog(module, op, {msg:'',s0:'',s1:'',etc:{}},callback)
 */
export function sendLog(module, op, logData, callback) {
  callback = callback || null;

  let methods = logData.event ? 'sc' : '';
  let logObj = buildLogInfo(logData);
  logObj = extend({module, op}, logObj);
  let logStr = JSON.stringify(logObj);
  console.log('[log_info]: ' + logStr);
  if (hasExternal('log_b')) {
    remoteLog(methods, logStr);
    if (callback && isFunction(callback)) {
      callback();
    }
  } else {
    let logChhannel = 'vox_logs:17middle_' + logObj.app;
    let logLevel = LOG_LEVEL.INFO;
    let time = new Date().getTime();

    let logParams = {
      _c: logChhannel,
      _l: logLevel,
      _log: encodeURIComponent(logStr),
      _t: time
    };

    let url = LOG_BASE_URL + '/log?';
    Object.keys(logParams).forEach(function (key) {
      url += key + '=' + logParams[key] + '&';
    });
    url = trimURL(url.slice(0, -1));

    let image = new Image();
    if (callback && isFunction(callback)) {
      image.onload = image.onerror = function () {
        callback();
      };
    }

    image.src = url;
  }
}

/**
 * 错误上报
 * @param {string|Object} error
 * @param {string} category
 * @param {string} level
 */
export function errorReport(error, category, level) {
  category = category || 'js_console';

  let logChhannel = 'middle:frontend_error';
  let logLevel = level || LOG_LEVEL.ERROR;

  let reportHost = window.errorReportHost || ERROR_REPORT_URL;

  try {
    if (typeof error != 'object') {
      error = {msg: error};
    }
    if (!error.url) {
      error.url = document.location.href;
    }

    let time = new Date().getTime();
    let logObj = buildLogInfo(error);
    logObj.error_type = category;
    let logStr = JSON.stringify(logObj);

    let logParams = {
      _c: logChhannel,
      _l: logLevel,
      _log: encodeURIComponent(logStr),
      _t: time
    };

    let url = reportHost + '/log?';
    Object.keys(logParams).forEach(function (key) {
      url += key + '=' + logParams[key] + '&';
    });
    url = trimURL(url.slice(0, -1));

    let image = new Image();
    image.src = url;
  } catch (e) {
    console.log('errorReport failed!');
  }
}

  

posted @ 2019-02-13 18:46  无工时代  阅读(868)  评论(0)    收藏  举报