Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/browser_reporting.js
6171 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
if (globalThis.disableErrorReporting) {
64
console.error(`ignoring top level error: ${message}`);
65
return;
66
}
67
console.error(`got top level error: ${message}`);
68
if (message.includes('unwind')) return;
69
var offset = message.indexOf('exit(');
70
if (offset != -1) {
71
var status = message.substring(offset + 5);
72
offset = status.indexOf(')')
73
status = status.substr(0, offset)
74
console.error(status);
75
var result = `exit:${status}`;
76
} else {
77
if (hasModule) Module['pageThrewException'] = true;
78
result = `exception:${message} / ${e.stack}`;
79
}
80
// FIXME: Ideally we would just reportResultToServer rather than the `maybe`
81
// form but some browser tests currently report exceptions after exit.
82
maybeReportResultToServer(result);
83
}
84
85
if (typeof window === 'object' && window) {
86
const urlString = window.location.search;
87
const searchParams = new URLSearchParams(urlString);
88
if (searchParams.has('capture_stdio')) {
89
captureStdio = true;
90
}
91
92
window.addEventListener('error', event => {
93
reportTopLevelError(event.error || event)
94
});
95
window.addEventListener('unhandledrejection', event => reportTopLevelError(event.reason));
96
}
97
98
if (hasModule) {
99
if (!Module['onExit']) {
100
Module['onExit'] = function(status) {
101
// If Module['REPORT_EXIT'] is set to false, do not report the result of
102
// onExit.
103
if (Module['REPORT_EXIT'] !== false) {
104
maybeReportResultToServer(`exit:${status}`);
105
}
106
}
107
// Force these handlers to be proxied back to the main thread.
108
// Without this tagging the handler will run each thread, which means
109
// each thread uses its own copy of `maybeReportResultToServer` which
110
// breaks the checking for duplicate reporting.
111
Module['onExit'].proxy = true;
112
}
113
114
if (!Module['onAbort']) {
115
Module['onAbort'] = (reason) => {
116
if (globalThis.disableErrorReporting) return;
117
maybeReportResultToServer(`abort:${reason}`);
118
};
119
Module['onAbort'].proxy = true;
120
}
121
122
if (captureStdio) {
123
console.log("enabling remote stdio logging");
124
const origPrint = Module['print'];
125
const origPrintErr = Module['printErr'];
126
127
Module['print'] = (...args) => {
128
origPrint && origPrint(args);
129
reportStdoutToServer(args.join(' '));
130
};
131
132
Module['printErr'] = (...args) => {
133
origPrintErr && origPrintErr(args);
134
reportStderrToServer(args.join(' '));
135
};
136
}
137
}
138
139