@jianghujs/jianghu
Version:
Progressive Enterprise Framework
130 lines (127 loc) • 4.51 kB
HTML
<!-- htmlErrorCollectionV4.html >>>>>>>>>> -->
{% if ctx.app.config.jianghuConfig.enableHtmlErrorLogRecord %}
<!-- htmlErrorCollectionV4.html >>>>>>>>>> -->
<script>
const errorCollectionFunc = ({
runtimeError = true,
rejectError = true,
consoleError = false,
unhandledCodeArr = [],
unhandledStringArr = [],
callback
}) => {
if (runtimeError) {
//JS运行时错误和资源加载错误
window.addEventListener(
'error',
({ error, target }) => {
if (target.outerHTML) {
//img error collection
const errLog = `${JSON.stringify(target.outerHTML)}`
callback(errLog)
} else {
const errLog = `${error?.stack?.substr(0, 300)}`
callback(errLog)
}
},
//use Event capture to collection img error
true
)
}
if (rejectError) {
//promise被reject并且错误信息没有被处理的时候,会抛出一个unhandledrejection
//接口错误处理,cross origin , 404,401
window.addEventListener('unhandledrejection', ({ reason }) => {
let errLog = ''
if (typeof reason === 'string') {
errLog = reason
} else if (reason instanceof Object) {
errLog = JSON.stringify(reason)
} else {
errLog = '未知类型'
}
//此处可添加不捕捉状态码
const unhandledCode = '403,401'
//此处可添加不捕捉string
const unhandledString = 'cancel'
for (let string of unhandledCode.split(',').concat(unhandledCodeArr)) {
if (errLog.includes(string)) {
return
}
}
for (let string of unhandledString.split(',').concat(unhandledStringArr)) {
if (errLog.includes(string)) {
return
}
}
callback(errLog)
})
}
if (consoleError) {
//些特殊情况下,还需要捕获处理console.error,捕获方式就是重写window.console.error
const _oldConsoleError = window.console.error
window.console.error = function () {
// eslint-disable-next-line prefer-rest-params
const errLog = Object.values(arguments).join(',')
if (errLog.indexOf('custom') === -1) {
callback(errLog)
}
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
_oldConsoleError && _oldConsoleError.apply(window, arguments)
}
}
}
const pushErrorLogToLocalStorageFunc = (errorLog) => {
let errorLogList = [];
try {
errorLogList = JSON.parse(localStorage.getItem(`${window.appInfo.appId}_errorLogList`) || '[]');
} catch (error) {
console.log("[pushErrorLogToLocalStorage] JSON.parse error", error);
}
errorLogList.push(errorLog);
if (errorLogList.length > 500) {
errorLogList.splice(0, 100);
}
localStorage.setItem(`${window.appInfo.appId}_errorLogList`, JSON.stringify(errorLogList));
}
const intervalSyncErrorLogListToServerFunc = ({ intervalTimeout }) => {
setInterval(() => {
let errorLogList = [];
try {
errorLogList = JSON.parse(localStorage.getItem(`${window.appInfo.appId}_errorLogList`) || '[]');
} catch (error) {
console.log("JSON.parse error", error);
}
if (errorLogList.length > 0) {
localStorage.setItem(`${window.appInfo.appId}_errorLogList`, '[]');
window.jianghuAxios({
data: {
appData: {
pageId: 'allPage',
actionId: 'htmlErrorLogRecord',
actionData: { errorLogList }
}
}
})
}
}, intervalTimeout);
}
errorCollectionFunc({
runtimeError: true, rejectError: true, consoleError: true,
callback: (errorMessage) => {
try {
const errorTime = dayjs().format();
const userId = localStorage.getItem(`${window.appInfo.authTokenKey}_userId`);
const deviceId = localStorage.getItem(`${window.appInfo.authTokenKey}_deviceId`);
pushErrorLogToLocalStorageFunc({ userId, deviceId, errorTime, errorMessage });
} catch (error) {
console.log("[errorCollection.html] 异常日志记录异常!", error)
}
}
})
const intervalTimeout = '<$ ctx.app.config.jianghuConfig.htmlErrorLogRecordInterval $>' || 60000;
intervalSyncErrorLogListToServerFunc({ intervalTimeout });
</script>
<!-- htmlErrorCollectionV4.html <<<<<<<<<<<< -->
{% endif %}