南锋

南奔万里空,脱死锋镝余

cocosCreator全局错误监听及错误的解决方法

我们在使用cocosCreator开发游戏,如果游戏上线,出现了bug我们一般是不知道的,除了玩家反馈。而且算有玩家反馈,也不知道具体是哪里出现了问题。我这里是做了一个全局的错误监听,然后将错误日志上报到服务器,然后通过上报的错误日志来定位问题。甚至可以发现很多玩家没有反馈到的bug。

创建全局错误监听

这里注意,不同的错误类型监听方法不一样,而且只在web端生效,如果是原生端,这里的监听是不会上报的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
window.onerror = (message, source, lineno, colno, error) => {
if (lineno != lineno1 && colno1 != lineno && message != message1) {
HttpReq.Ins.reqDotting(error, { type: `5`, content: `捕获到全局错误:来源: ${source},行号: ${lineno},列号: ${colno}`, additional: `错误对象: ${error}` });
}
lineno1 = lineno;
colno1 = colno;
message1 = message;
return true;
};

window.addEventListener("unhandledrejection", (event) => {
// console.error("未处理的 Promise 异常:", event.reason);
let errorInfo = {
message: "",
stack: "",
};

if (event.reason instanceof Error) {
// 如果event.reason是一个Error对象,获取错误消息和堆栈信息
errorInfo.message = event.reason.message;
errorInfo.stack = event.reason.stack;
} else {
// 如果不是一个Error对象,直接使用toString()方法尝试获取有用的信息
errorInfo.message = event.reason.toString();
}
const errorInfoString = JSON.stringify(errorInfo);
HttpReq.Ins.reqDotting(ClientDottingName.error, { type: `3`, content: `未处理的 Promise 异常`, additional: `${errorInfoString}` });
});

window.addEventListener("error", (event) => {
const target = event.target as HTMLElement;
if (target && (target.tagName === "IMG" || target.tagName === "SCRIPT" || target.tagName === "LINK")) {
HttpReq.Ins.reqDotting(error, { type: `4`, content: `资源加载失败:`, additional: `${target.getAttribute("src") || target.getAttribute("href")}` });
}
}, true);

这里需要注意几点:

  1. 上报的接口要改成你自己的,我这里是随便写的一个
  2. 在捕获全局错误window.onerror时,一旦触发可能就是无限触发,会导致游戏卡死的那种,只有杀掉进程才能恢复。所以我做了一个判断,如果行号和列号和上一次相同,并且错误信息相同,则不再上报,减少服务器的压力。

查看问题及解决方法

cocosCreator导出后的代码和源码进行对比;

+