Nanfeng

Notes on software development, code, and curious ideas

Global Error Handling in Cocos Creator Web Builds

After a game is released, bugs can be invisible until a player reports them—and even then, the report may not reveal where the problem occurred. I added global error listeners and sent diagnostics to a server, which also uncovered errors that players never reported.

Register global listeners

Different error types require different listeners. This implementation applies only to web builds; native builds will not report through these browser APIs.

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
36
37
38
39
40
41
window.onerror = (message, source, lineno, colno, error) => {
if (lineno != lineno1 && colno1 != lineno && message != message1) {
HttpReq.Ins.reqDotting(error, {
type: `5`,
content: `Global error: source ${source}, line ${lineno}, column ${colno}`,
additional: `Error object: ${error}`
});
}
lineno1 = lineno;
colno1 = colno;
message1 = message;
return true;
};

window.addEventListener('unhandledrejection', (event) => {
const errorInfo = { message: '', stack: '' };

if (event.reason instanceof Error) {
errorInfo.message = event.reason.message;
errorInfo.stack = event.reason.stack;
} else {
errorInfo.message = event.reason.toString();
}

HttpReq.Ins.reqDotting(ClientDottingName.error, {
type: `3`,
content: `Unhandled Promise rejection`,
additional: JSON.stringify(errorInfo)
});
});

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: `Resource failed to load`,
additional: `${target.getAttribute('src') || target.getAttribute('href')}`
});
}
}, true);

Replace the reporting calls with your own API. Also rate-limit and deduplicate reports: a global error can fire repeatedly and overwhelm both the game and the server. This example avoids reporting the same line, column, and message repeatedly.

To map a production stack trace back to source, see Mapping Cocos Creator Production Errors Back to Source Code.

+