reporting-lib
Version:
A comprehensive monitoring and reporting library for web applications
105 lines • 4.09 kB
JavaScript
import { lazyReportCache } from "../report/index.js";
import { detectionWhiteScreen, getFullBrowserInfo, getOSInfo, toReadableString } from '../util/tool.js';
import { version } from '../config/index.js';
const browserInfor = getFullBrowserInfo();
const reportData = {
user_agent: browserInfor.name + browserInfor.version,
platform: getOSInfo(),
};
/**
* 这个正则表达式用于匹配 JavaScript 错误栈中的堆栈跟踪信息中的单个条目,其中包含文件名、行号和列号等信息。
* 具体来说,它匹配以下格式的文本:
* at functionName (filename:lineNumber:columnNumber)
* at filename:lineNumber:columnNumber
* at http://example.com/filename:lineNumber:columnNumber
* at https://example.com/filename:lineNumber:columnNumber
*/
const FULL_MATCH = /^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
//限制追溯的错误堆栈数量
const STACK_TRACE_LIMIT = 10;
//通过正则表达式解析一行的错误信息
function parseStackLine(line) {
const lineMatch = line.match(FULL_MATCH);
if (!lineMatch)
return {};
const filename = lineMatch[2] || '<anonymous>';
const functionName = lineMatch[1] || '';
const lineno = parseInt(lineMatch[3], 10) || undefined;
const colno = parseInt(lineMatch[4], 10) || undefined;
return {
filename,
functionName,
lineno,
colno
};
}
//解析错误堆栈
function parseStackFrames(error) {
const { stack } = error;
//如果没有stack直接返回[]
if (!stack)
return [];
const frames = [];
for (const line of stack.split('\n').slice(1)) {
const frame = parseStackLine(line); //分析一行的错误信息
if (frame.filename) {
//放入到堆栈错误信息数组中
frames.push(frame);
}
}
return frames.slice(0, STACK_TRACE_LIMIT);
}
export default function error() {
//资源错误没有冒泡,所以只能在捕获阶段采集获取错误
window.addEventListener('error', async function (event) {
const target = event.target;
//要判断是资源错误,还是js错误,很简单,直接判断事件对象有没有src或者href属性就可以了
if (target && (target.src || target.href)) {
//上报资源错误 todo...
const data = {
error_type: 'resource',
...reportData,
msg: toReadableString(`加载${target.tagName}失败:${target.src || target.href}`),
version,
};
lazyReportCache('error', data);
}
else {
const errs = parseStackFrames(event.error);
let msg = event.message;
if (errs?.[0]) {
const { filename, functionName, lineno, colno } = errs[0];
msg = `${event.message},${filename},line:${lineno}:${colno}`;
}
const data = {
error_type: 'js',
msg: toReadableString(msg),
...reportData,
version,
};
lazyReportCache('error', data);
const isWhite = await detectionWhiteScreen();
if (isWhite) {
lazyReportCache('error', { ...data, error_type: 'whiteScreen' });
}
}
}, true);
//promise错误
window.addEventListener('unhandledrejection', function (event) {
const reason = event.reason;
const errs = parseStackFrames(reason);
let msg = reason;
if (errs?.[0]) {
const { filename, functionName, lineno, colno } = errs[0];
msg = `${event?.reason?.message || event?.reason},${filename},line:${lineno}:${colno}`;
}
const data = {
error_type: 'js',
msg: toReadableString(msg),
...reportData,
version,
};
lazyReportCache('error', data);
});
}
//# sourceMappingURL=index.js.map