制作无错误的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!');
}
}

浙公网安备 33010602011771号