在index.html添加promise错误的捕获

This commit is contained in:
nonameShijian 2024-02-16 17:33:42 +08:00
parent 054afb0976
commit 7c9d806782
3 changed files with 85 additions and 13 deletions

View File

@ -141,7 +141,7 @@ new Promise(resolve => {
module._compile(require('fs').readFileSync(filename, 'utf8'), filename); module._compile(require('fs').readFileSync(filename, 'utf8'), filename);
}; };
} }
if (location.protocol.startsWith('http') && 'serviceWorker' in navigator) { if (window.isSecureContext && 'serviceWorker' in navigator) {
let scope = window.location.protocol + '//' + window.location.host + '/'; let scope = window.location.protocol + '//' + window.location.host + '/';
navigator.serviceWorker.getRegistrations().then(registrations => { navigator.serviceWorker.getRegistrations().then(registrations => {
let findServiceWorker = registrations.find(registration => { let findServiceWorker = registrations.find(registration => {

View File

@ -1,4 +1,5 @@
<!DOCTYPE HTML> <!DOCTYPE HTML>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
@ -6,6 +7,7 @@
<meta name="viewport" content="user-scalable=no, viewport-fit=cover"> <meta name="viewport" content="user-scalable=no, viewport-fit=cover">
<title>无名杀</title> <title>无名杀</title>
<script> <script>
(() => {
window.onerror = function (msg, src, line, column, err) { window.onerror = function (msg, src, line, column, err) {
let str = `错误文件: ${typeof src == 'string' && src.length > 0 ? decodeURI(src) : '未知文件'}`; let str = `错误文件: ${typeof src == 'string' && src.length > 0 ? decodeURI(src) : '未知文件'}`;
str += `\n错误信息: ${msg}`; str += `\n错误信息: ${msg}`;
@ -15,10 +17,80 @@
console.error(str); console.error(str);
alert(str); alert(str);
}; };
const STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
const errorList = [];
window.onunhandledrejection = async event => {
event.promise.catch(error => {
console.log(error);
// 如果`error`是个错误,则继续处理
if (error instanceof Error) {
// 如果已经处理过该错误,则不再处理
if (errorList.includes(error)) return;
errorList.push(error);
// 如果`error`拥有字符串形式的报错栈堆且报错栈堆确实符合v8的stack
if (typeof error.stack === 'string' && STACK_REGEXP.test(error.stack)) {
// 获取符合栈堆信息的字符串,一般来说就是从第二行开始的所有行
// 为了处理eval的情况故必须获取完行数
let lines = error.stack.split('\n').filter((line) =>
STACK_REGEXP.test(line));
// 提供类型信息防止vscode报错
/**
* @type {string | undefined}
*/
let fileName = void 0;
/**
* @type {number | undefined}
*/
let line = void 0;
/**
* @type {number | undefined}
*/
let column = void 0;
// 从第一条开始遍历一直遍历到不存在eval的位置
for (let currentLine = 0; currentLine < lines.length; ++currentLine) {
if (/\(eval /.test(lines[currentLine])) continue;
let formatedLine = lines[currentLine].replace(/^\s+/, '').replace(/\(eval code/g, '(').replace(/^.*?\s+/, '');
const location = formatedLine.match(/ (\(.+\)$)/);
if (location) formatedLine = formatedLine.replace(location[0], '');
const locationParts = extractLocation(location ? location[1] : formatedLine);
fileName = ['eval', '<anonymous>'].includes(locationParts[0]) ? void 0 : locationParts[0];
line = Number(locationParts[1]);
column = Number(locationParts[2]);
break;
}
// @ts-ignore
window.onerror(error.message, fileName, line, column, error);
}
// 反之我们只能不考虑报错文件信息直接调用onerror
else {
try {
// @ts-ignore
let [_, src = void 0, line = void 0, column = void 0] = /at\s+.*\s+\((.*):(\d*):(\d*)\)/i.exec(error.stack.split('\n')[1])
if (typeof line == 'string') line = Number(line);
if (typeof column == 'string') column = Number(column);
// @ts-ignore
window.onerror(error.message, src, line, column, error);
} catch (e) {
window.onerror(error.message, '', 0, 0, error);
}
}
}
});
};
})();
</script> </script>
<script> <script>
if (location.href.startsWith('http') && typeof window.initReadWriteFunction != 'function' && !window.require && !window.__dirname) { if (location.href.startsWith('http') && typeof window.initReadWriteFunction != 'function' && !window.require && !window.__dirname) {
window.initReadWriteFunction = async function(game) { window.initReadWriteFunction = async function (game) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fetch(`./readFile?fileName=noname.js`) fetch(`./readFile?fileName=noname.js`)
.then(response => { .then(response => {

View File

@ -846,9 +846,9 @@ async function setOnError() {
if (promiseErrorHandler.onLoad) await promiseErrorHandler.onLoad(); if (promiseErrorHandler.onLoad) await promiseErrorHandler.onLoad();
window.addEventListener("unhandledrejection", async (event) => { window.onunhandledrejection = async (event) => {
if (promiseErrorHandler.onHandle) await promiseErrorHandler.onHandle(event); if (promiseErrorHandler.onHandle) await promiseErrorHandler.onHandle(event);
}); };
window.onerror = function (msg, src, line, column, err) { window.onerror = function (msg, src, line, column, err) {
if (promiseErrorHandler.onErrorPrepare) promiseErrorHandler.onErrorPrepare(); if (promiseErrorHandler.onErrorPrepare) promiseErrorHandler.onErrorPrepare();