Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/browser_reporting.js
4128 views
1
// Set this to true to have stdout and stderr sent back to the server
2
var captureStdio = false;
3
4
var hasModule = typeof Module === 'object' && Module;
5
6
var reportingURL = '{{{REPORTING_URL}}}';
7
8
async function reportResultToServer(result) {
9
if (reportResultToServer.reported) {
10
// Only report one result per test, even if the test misbehaves and tries to report more.
11
reportStderrToServer(`excessive reported results, sending ${result}, test will fail`);
12
}
13
reportResultToServer.reported = true;
14
if ((typeof ENVIRONMENT_IS_NODE !== 'undefined' && ENVIRONMENT_IS_NODE) || (typeof ENVIRONMENT_IS_AUDIO_WORKLET !== 'undefined' && ENVIRONMENT_IS_AUDIO_WORKLET)) {
15
out(`RESULT: ${result}`);
16
} else {
17
await fetch(`${reportingURL}/report_result?${encodeURIComponent(result)}`);
18
if (typeof window === 'object' && window && hasModule && !Module['pageThrewException']) {
19
/* for easy debugging, don't close window on failure */
20
window.close();
21
}
22
}
23
}
24
25
function sendFileToServer(filename, contents) {
26
fetch(`${reportingURL}/upload?file=${encodeURIComponent(filename)}`, { method: "POST", body: contents });
27
}
28
29
function logMessageToServer(filename, message) {
30
fetch(`${reportingURL}/log?file=${filename}`, { method: "POST", body: message })
31
}
32
33
function maybeReportResultToServer(result) {
34
if (!reportResultToServer.reported) {
35
reportResultToServer(result);
36
}
37
}
38
39
function reportStderrToServer(message) {
40
if (typeof ENVIRONMENT_IS_NODE !== 'undefined' && ENVIRONMENT_IS_NODE) {
41
err(message);
42
} else {
43
logMessageToServer('stderr', message);
44
}
45
}
46
47
function reportStdoutToServer(message) {
48
if (typeof ENVIRONMENT_IS_NODE !== 'undefined' && ENVIRONMENT_IS_NODE) {
49
out(message);
50
} else {
51
logMessageToServer('stdout', message);
52
}
53
}
54
55
async function skipTest(message) {
56
await reportResultToServer(`skipped:${message}`);
57
}
58
59
function reportTopLevelError(e) {
60
// MINIMAL_RUNTIME doesn't handle exit or call the below onExit handler
61
// so we detect the exit by parsing the uncaught exception message.
62
var message = e.message || e;
63
console.error(`got top level error: ${message}`);
64
if (window.disableErrorReporting) return;
65
if (message.includes('unwind')) return;
66
var offset = message.indexOf('exit(');
67
if (offset != -1) {
68
var status = message.substring(offset + 5);
69
offset = status.indexOf(')')
70
status = status.substr(0, offset)
71
console.error(status);
72
var result = `exit:${status}`;
73
} else {
74
if (hasModule) Module['pageThrewException'] = true;
75
result = `exception:${message} / ${e.stack}`;
76
}
77
// FIXME: Ideally we would just reportResultToServer rather than the `maybe`
78
// form but some browser tests currently report exceptions after exit.
79
maybeReportResultToServer(result);
80
}
81
82
if (typeof window === 'object' && window) {
83
const urlString = window.location.search;
84
const searchParams = new URLSearchParams(urlString);
85
if (searchParams.has('capture_stdio')) {
86
captureStdio = true;
87
}
88
89
window.addEventListener('error', event => {
90
reportTopLevelError(event.error || event)
91
});
92
window.addEventListener('unhandledrejection', event => reportTopLevelError(event.reason));
93
}
94
95
if (hasModule) {
96
if (!Module['onExit']) {
97
Module['onExit'] = function(status) {
98
// If Module['REPORT_EXIT'] is set to false, do not report the result of
99
// onExit.
100
if (Module['REPORT_EXIT'] !== false) {
101
maybeReportResultToServer(`exit:${status}`);
102
}
103
}
104
// Force these handlers to be proxied back to the main thread.
105
// Without this tagging the handler will run each thread, which means
106
// each thread uses its own copy of `maybeReportResultToServer` which
107
// breaks the checking for duplicate reporting.
108
Module['onExit'].proxy = true;
109
}
110
111
if (!Module['onAbort']) {
112
Module['onAbort'] = function(reason) {
113
maybeReportResultToServer(`abort:${reason}`);
114
}
115
Module['onAbort'].proxy = true;
116
}
117
118
if (captureStdio) {
119
console.log("enabling remote stdio logging");
120
const origPrint = Module['print'];
121
const origPrintErr = Module['printErr'];
122
123
Module['print'] = (...args) => {
124
origPrint?.(...args);
125
reportStdoutToServer(args.join(' '));
126
};
127
128
Module['printErr'] = (...args) => {
129
origPrintErr?.(...args);
130
reportStderrToServer(args.join(' '));
131
};
132
}
133
}
134
135