@jsenv/core 27.3.2 → 27.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -4
- package/dist/controllable_child_process.mjs +1 -0
- package/dist/controllable_worker_thread.mjs +1 -0
- package/dist/js/event_source_client.js +45 -24
- package/dist/js/execute_using_dynamic_import.js +5 -3
- package/dist/js/html_supervisor_installer.js +368 -139
- package/dist/main.js +668 -471
- package/package.json +5 -6
- package/src/build/build.js +6 -4
- package/src/build/graph_utils.js +14 -11
- package/src/execute/run.js +29 -28
- package/src/execute/runtimes/browsers/from_playwright.js +90 -92
- package/src/execute/runtimes/node/execute_using_dynamic_import.js +8 -2
- package/src/execute/runtimes/node/node_child_process.js +2 -0
- package/src/execute/runtimes/node/node_worker_thread.js +11 -6
- package/src/helpers/event_source/event_source.js +38 -17
- package/src/omega/errors.js +41 -9
- package/src/omega/kitchen.js +35 -19
- package/src/omega/omega_server.js +54 -1
- package/src/omega/server/file_service.js +30 -3
- package/src/omega/url_graph/url_graph_report.js +2 -4
- package/src/omega/url_graph.js +29 -16
- package/src/plugins/autoreload/dev_sse/client/event_source_client.js +8 -8
- package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +160 -172
- package/src/plugins/autoreload/jsenv_plugin_autoreload.js +0 -4
- package/src/plugins/bundling/js_module/bundle_js_module.js +0 -1
- package/src/plugins/html_supervisor/client/error_in_document.js +268 -121
- package/src/plugins/html_supervisor/client/html_supervisor_installer.js +47 -5
- package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +37 -12
- package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +1 -2
- package/src/plugins/plugins.js +0 -2
- package/src/plugins/url_analysis/js/js_urls.js +0 -9
- package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +3 -1
- package/src/test/coverage/report_to_coverage.js +16 -11
- package/src/test/execute_plan.js +3 -2
- package/src/test/execute_test_plan.js +3 -1
- package/src/test/logs_file_execution.js +60 -27
- package/src/test/logs_file_execution.test.mjs +41 -0
|
@@ -10,109 +10,335 @@ const unevalException = value => {
|
|
|
10
10
|
});
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
13
|
+
const JSENV_ERROR_OVERLAY_TAGNAME = "jsenv-error-overlay";
|
|
14
|
+
const displayErrorInDocument = (error, {
|
|
15
|
+
rootDirectoryUrl,
|
|
16
|
+
url,
|
|
17
|
+
line,
|
|
18
|
+
column
|
|
19
|
+
}) => {
|
|
20
|
+
document.querySelectorAll(JSENV_ERROR_OVERLAY_TAGNAME).forEach(node => {
|
|
21
|
+
node.parentNode.removeChild(node);
|
|
22
|
+
});
|
|
23
|
+
const {
|
|
24
|
+
theme,
|
|
25
|
+
title,
|
|
26
|
+
message,
|
|
27
|
+
stack
|
|
28
|
+
} = errorToHTML(error, {
|
|
29
|
+
url,
|
|
30
|
+
line,
|
|
31
|
+
column
|
|
32
|
+
});
|
|
33
|
+
const jsenvErrorOverlay = new JsenvErrorOverlay({
|
|
34
|
+
theme,
|
|
35
|
+
title,
|
|
36
|
+
stack: stack ? `${replaceLinks(message, {
|
|
37
|
+
rootDirectoryUrl
|
|
38
|
+
})}\n${replaceLinks(stack, {
|
|
39
|
+
rootDirectoryUrl
|
|
40
|
+
})}` : replaceLinks(message, {
|
|
41
|
+
rootDirectoryUrl
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
document.body.appendChild(jsenvErrorOverlay);
|
|
45
|
+
};
|
|
32
46
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
class JsenvErrorOverlay extends HTMLElement {
|
|
48
|
+
constructor({
|
|
49
|
+
title,
|
|
50
|
+
stack,
|
|
51
|
+
theme = "dark"
|
|
52
|
+
}) {
|
|
53
|
+
super();
|
|
54
|
+
this.root = this.attachShadow({
|
|
55
|
+
mode: "open"
|
|
56
|
+
});
|
|
57
|
+
this.root.innerHTML = overlayHtml;
|
|
58
|
+
this.root.querySelector(".overlay").setAttribute("data-theme", theme);
|
|
59
|
+
this.root.querySelector(".title").innerHTML = title;
|
|
60
|
+
this.root.querySelector(".stack").innerHTML = stack;
|
|
61
|
+
|
|
62
|
+
this.root.querySelector(".backdrop").onclick = () => {
|
|
63
|
+
if (!this.parentNode) {
|
|
64
|
+
// not in document anymore
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
38
67
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
68
|
+
this.root.querySelector(".backdrop").onclick = null;
|
|
69
|
+
this.parentNode.removeChild(this);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
42
72
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (customElements && !customElements.get(JSENV_ERROR_OVERLAY_TAGNAME)) {
|
|
76
|
+
customElements.define(JSENV_ERROR_OVERLAY_TAGNAME, JsenvErrorOverlay);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const overlayHtml = `
|
|
80
|
+
<style>
|
|
81
|
+
:host {
|
|
82
|
+
position: fixed;
|
|
83
|
+
z-index: 99999;
|
|
84
|
+
top: 0;
|
|
85
|
+
left: 0;
|
|
86
|
+
width: 100%;
|
|
87
|
+
height: 100%;
|
|
88
|
+
overflow-y: scroll;
|
|
89
|
+
margin: 0;
|
|
90
|
+
background: rgba(0, 0, 0, 0.66);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.backdrop {
|
|
94
|
+
position: absolute;
|
|
95
|
+
left: 0;
|
|
96
|
+
right: 0;
|
|
97
|
+
top: 0;
|
|
98
|
+
bottom: 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.overlay {
|
|
102
|
+
position: relative;
|
|
103
|
+
background: rgba(0, 0, 0, 0.95);
|
|
104
|
+
width: 800px;
|
|
105
|
+
margin: 30px auto;
|
|
106
|
+
padding: 25px 40px;
|
|
107
|
+
padding-top: 0;
|
|
108
|
+
overflow: hidden; /* for h1 margins */
|
|
109
|
+
border-radius: 4px 8px;
|
|
110
|
+
box-shadow: 0 20px 40px rgb(0 0 0 / 30%), 0 15px 12px rgb(0 0 0 / 20%);
|
|
111
|
+
box-sizing: border-box;
|
|
112
|
+
font-family: monospace;
|
|
113
|
+
direction: ltr;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
h1 {
|
|
117
|
+
color: red;
|
|
118
|
+
text-align: center;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
pre {
|
|
122
|
+
overflow: auto;
|
|
123
|
+
max-width: 100%;
|
|
124
|
+
/* padding is nice + prevents scrollbar from hiding the text behind it */
|
|
125
|
+
/* does not work nicely on firefox though https://bugzilla.mozilla.org/show_bug.cgi?id=748518 */
|
|
126
|
+
padding: 20px;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.tip {
|
|
130
|
+
border-top: 1px solid #999;
|
|
131
|
+
padding-top: 12px;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
[data-theme="dark"] {
|
|
135
|
+
color: #999;
|
|
136
|
+
}
|
|
137
|
+
[data-theme="dark"] pre {
|
|
138
|
+
background: #111;
|
|
139
|
+
border: 1px solid #333;
|
|
140
|
+
color: #eee;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
[data-theme="light"] {
|
|
144
|
+
color: #EEEEEE;
|
|
145
|
+
}
|
|
146
|
+
[data-theme="light"] pre {
|
|
147
|
+
background: #1E1E1E;
|
|
148
|
+
border: 1px solid white;
|
|
149
|
+
color: #EEEEEE;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
pre a {
|
|
153
|
+
color: inherit;
|
|
154
|
+
}
|
|
155
|
+
</style>
|
|
156
|
+
<div class="backdrop"></div>
|
|
157
|
+
<div class="overlay">
|
|
158
|
+
<h1 class="title"></h1>
|
|
159
|
+
<pre class="stack"></pre>
|
|
160
|
+
<div class="tip">Click outside to close.</div>
|
|
161
|
+
</div>
|
|
162
|
+
`;
|
|
163
|
+
|
|
164
|
+
const parseErrorInfo = error => {
|
|
165
|
+
if (error === undefined) {
|
|
166
|
+
return {
|
|
167
|
+
message: "undefined"
|
|
168
|
+
};
|
|
169
|
+
}
|
|
49
170
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
171
|
+
if (error === null) {
|
|
172
|
+
return {
|
|
173
|
+
message: "null"
|
|
174
|
+
};
|
|
175
|
+
}
|
|
55
176
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
177
|
+
if (typeof error === "string") {
|
|
178
|
+
return {
|
|
179
|
+
message: error
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (error instanceof Error) {
|
|
184
|
+
if (error.name === "SyntaxError") {
|
|
185
|
+
return {
|
|
186
|
+
message: error.message
|
|
187
|
+
};
|
|
60
188
|
}
|
|
61
189
|
|
|
62
|
-
.
|
|
63
|
-
|
|
190
|
+
if (error.cause && error.cause.code === "PARSE_ERROR") {
|
|
191
|
+
if (error.messageHTML) {
|
|
192
|
+
return {
|
|
193
|
+
message: error.messageHTML
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
message: error.message
|
|
199
|
+
};
|
|
200
|
+
} // stackTrace formatted by V8
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
if (Error.captureStackTrace) {
|
|
204
|
+
return {
|
|
205
|
+
message: error.message,
|
|
206
|
+
stack: getErrorStackWithoutErrorMessage(error)
|
|
207
|
+
};
|
|
64
208
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
message: error.message,
|
|
212
|
+
stack: error.stack ? ` ${error.stack}` : null
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (typeof error === "object") {
|
|
217
|
+
return error;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
message: JSON.stringify(error)
|
|
77
222
|
};
|
|
78
223
|
};
|
|
79
224
|
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
}
|
|
225
|
+
const getErrorStackWithoutErrorMessage = error => {
|
|
226
|
+
let stack = error.stack;
|
|
227
|
+
const messageInStack = `${error.name}: ${error.message}`;
|
|
228
|
+
|
|
229
|
+
if (stack.startsWith(messageInStack)) {
|
|
230
|
+
stack = stack.slice(messageInStack.length);
|
|
231
|
+
}
|
|
83
232
|
|
|
84
|
-
const
|
|
85
|
-
let html;
|
|
233
|
+
const nextLineIndex = stack.indexOf("\n");
|
|
86
234
|
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
235
|
+
if (nextLineIndex > -1) {
|
|
236
|
+
stack = stack.slice(nextLineIndex + 1);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return stack;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const errorToHTML = (error, {
|
|
243
|
+
url,
|
|
244
|
+
line,
|
|
245
|
+
column
|
|
246
|
+
}) => {
|
|
247
|
+
let {
|
|
248
|
+
message,
|
|
249
|
+
stack
|
|
250
|
+
} = parseErrorInfo(error);
|
|
251
|
+
|
|
252
|
+
if (url) {
|
|
253
|
+
if (!stack || error && error.name === "SyntaxError") {
|
|
254
|
+
stack = ` at ${appendLineAndColumn(url, {
|
|
255
|
+
line,
|
|
256
|
+
column
|
|
257
|
+
})}`;
|
|
97
258
|
}
|
|
98
|
-
} else if (typeof error === "string") {
|
|
99
|
-
html = error;
|
|
100
|
-
} else if (error === undefined) {
|
|
101
|
-
html = "undefined";
|
|
102
|
-
} else {
|
|
103
|
-
html = JSON.stringify(error);
|
|
104
259
|
}
|
|
105
260
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
261
|
+
return {
|
|
262
|
+
theme: error && error.cause && error.cause.code === "PARSE_ERROR" ? "light" : "dark",
|
|
263
|
+
title: "An error occured",
|
|
264
|
+
message,
|
|
265
|
+
stack
|
|
266
|
+
};
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
const replaceLinks = (string, {
|
|
270
|
+
rootDirectoryUrl
|
|
271
|
+
}) => {
|
|
272
|
+
// normalize line breaks
|
|
273
|
+
string = string.replace(/\n/g, "\n");
|
|
274
|
+
string = escapeHtml(string); // render links
|
|
275
|
+
|
|
276
|
+
string = stringToStringWithLink(string, {
|
|
277
|
+
transform: (url, {
|
|
278
|
+
line,
|
|
279
|
+
column
|
|
280
|
+
}) => {
|
|
281
|
+
const urlObject = new URL(url);
|
|
282
|
+
|
|
283
|
+
const onFileUrl = fileUrlObject => {
|
|
284
|
+
const atFsIndex = fileUrlObject.pathname.indexOf("/@fs/");
|
|
285
|
+
let fileUrl;
|
|
286
|
+
|
|
287
|
+
if (atFsIndex > -1) {
|
|
288
|
+
const afterAtFs = fileUrlObject.pathname.slice(atFsIndex + "/@fs/".length);
|
|
289
|
+
fileUrl = new URL(afterAtFs, "file:///").href;
|
|
290
|
+
} else {
|
|
291
|
+
fileUrl = fileUrlObject.href;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
fileUrl = appendLineAndColumn(fileUrl, {
|
|
295
|
+
line,
|
|
296
|
+
column
|
|
297
|
+
});
|
|
298
|
+
return link({
|
|
299
|
+
href: `javascript:window.fetch('/__open_in_editor__/${fileUrl}')`,
|
|
300
|
+
text: fileUrl
|
|
301
|
+
});
|
|
112
302
|
};
|
|
303
|
+
|
|
304
|
+
if (urlObject.origin === window.origin) {
|
|
305
|
+
const fileUrlObject = new URL(`${urlObject.pathname.slice(1)}${urlObject.search}`, rootDirectoryUrl);
|
|
306
|
+
return onFileUrl(fileUrlObject);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (urlObject.href.startsWith("file:")) {
|
|
310
|
+
return onFileUrl(urlObject);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return link({
|
|
314
|
+
href: url,
|
|
315
|
+
text: appendLineAndColumn(url, {
|
|
316
|
+
line,
|
|
317
|
+
column
|
|
318
|
+
})
|
|
319
|
+
});
|
|
113
320
|
}
|
|
114
321
|
});
|
|
115
|
-
return
|
|
322
|
+
return string;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
const escapeHtml = string => {
|
|
326
|
+
return string.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const appendLineAndColumn = (url, {
|
|
330
|
+
line,
|
|
331
|
+
column
|
|
332
|
+
}) => {
|
|
333
|
+
if (line !== undefined && column !== undefined) {
|
|
334
|
+
return `${url}:${line}:${column}`;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (line !== undefined) {
|
|
338
|
+
return `${url}:${line}`;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return url;
|
|
116
342
|
}; // `Error: yo
|
|
117
343
|
// at Object.execute (http://127.0.0.1:57300/build/src/__test__/file-throw.js:9:13)
|
|
118
344
|
// at doExec (http://127.0.0.1:3000/src/__test__/file-throw.js:452:38)
|
|
@@ -147,14 +373,9 @@ const stringToStringWithLink = (source, {
|
|
|
147
373
|
const lineAndColumnString = lineAndColumMatch[0];
|
|
148
374
|
const lineNumber = lineAndColumMatch[1];
|
|
149
375
|
const columnNumber = lineAndColumMatch[2];
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
text
|
|
154
|
-
} = transform(url);
|
|
155
|
-
linkHTML = link({
|
|
156
|
-
href,
|
|
157
|
-
text: `${text}:${lineNumber}:${columnNumber}`
|
|
376
|
+
linkHTML = transform(match.slice(0, -lineAndColumnString.length), {
|
|
377
|
+
line: lineNumber,
|
|
378
|
+
column: columnNumber
|
|
158
379
|
});
|
|
159
380
|
} else {
|
|
160
381
|
const linePattern = /:([0-9]+)$/;
|
|
@@ -163,25 +384,11 @@ const stringToStringWithLink = (source, {
|
|
|
163
384
|
if (lineMatch) {
|
|
164
385
|
const lineString = lineMatch[0];
|
|
165
386
|
const lineNumber = lineMatch[1];
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
href,
|
|
169
|
-
text
|
|
170
|
-
} = transform(url);
|
|
171
|
-
linkHTML = link({
|
|
172
|
-
href,
|
|
173
|
-
text: `${text}:${lineNumber}`
|
|
387
|
+
linkHTML = transform(match.slice(0, -lineString.length), {
|
|
388
|
+
line: lineNumber
|
|
174
389
|
});
|
|
175
390
|
} else {
|
|
176
|
-
|
|
177
|
-
const {
|
|
178
|
-
href,
|
|
179
|
-
text
|
|
180
|
-
} = transform(url);
|
|
181
|
-
linkHTML = link({
|
|
182
|
-
href,
|
|
183
|
-
text
|
|
184
|
-
});
|
|
391
|
+
linkHTML = transform(match, {});
|
|
185
392
|
}
|
|
186
393
|
}
|
|
187
394
|
|
|
@@ -198,31 +405,6 @@ const link = ({
|
|
|
198
405
|
text = href
|
|
199
406
|
}) => `<a href="${href}">${text}</a>`;
|
|
200
407
|
|
|
201
|
-
const appendHMTLInside = (html, parentNode) => {
|
|
202
|
-
const temoraryParent = document.createElement("div");
|
|
203
|
-
temoraryParent.innerHTML = html;
|
|
204
|
-
return transferChildren(temoraryParent, parentNode);
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const transferChildren = (fromNode, toNode) => {
|
|
208
|
-
const childNodes = [].slice.call(fromNode.childNodes, 0);
|
|
209
|
-
let i = 0;
|
|
210
|
-
|
|
211
|
-
while (i < childNodes.length) {
|
|
212
|
-
toNode.appendChild(childNodes[i]);
|
|
213
|
-
i++;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
return () => {
|
|
217
|
-
let c = 0;
|
|
218
|
-
|
|
219
|
-
while (c < childNodes.length) {
|
|
220
|
-
fromNode.appendChild(childNodes[c]);
|
|
221
|
-
c++;
|
|
222
|
-
}
|
|
223
|
-
};
|
|
224
|
-
};
|
|
225
|
-
|
|
226
408
|
const {
|
|
227
409
|
Notification
|
|
228
410
|
} = window;
|
|
@@ -252,7 +434,8 @@ const {
|
|
|
252
434
|
} = window;
|
|
253
435
|
const installHtmlSupervisor = ({
|
|
254
436
|
logs,
|
|
255
|
-
measurePerf
|
|
437
|
+
measurePerf,
|
|
438
|
+
rootDirectoryUrl
|
|
256
439
|
}) => {
|
|
257
440
|
|
|
258
441
|
const scriptExecutionResults = {};
|
|
@@ -289,14 +472,14 @@ const installHtmlSupervisor = ({
|
|
|
289
472
|
const onExecutionError = (executionResult, {
|
|
290
473
|
currentScript,
|
|
291
474
|
errorExposureInNotification = false,
|
|
292
|
-
errorExposureInDocument =
|
|
475
|
+
errorExposureInDocument = false
|
|
293
476
|
}) => {
|
|
294
477
|
const error = executionResult.error;
|
|
295
478
|
|
|
296
479
|
if (error && error.code === "NETWORK_FAILURE") {
|
|
297
480
|
if (currentScript) {
|
|
298
|
-
const
|
|
299
|
-
currentScript.dispatchEvent(
|
|
481
|
+
const currentScriptErrorEvent = new Event("error");
|
|
482
|
+
currentScript.dispatchEvent(currentScriptErrorEvent);
|
|
300
483
|
}
|
|
301
484
|
} else if (typeof error === "object") {
|
|
302
485
|
const globalErrorEvent = new Event("error");
|
|
@@ -312,7 +495,9 @@ const installHtmlSupervisor = ({
|
|
|
312
495
|
}
|
|
313
496
|
|
|
314
497
|
if (errorExposureInDocument) {
|
|
315
|
-
displayErrorInDocument(error
|
|
498
|
+
displayErrorInDocument(error, {
|
|
499
|
+
rootDirectoryUrl
|
|
500
|
+
});
|
|
316
501
|
}
|
|
317
502
|
|
|
318
503
|
executionResult.exceptionSource = unevalException(error);
|
|
@@ -467,6 +652,50 @@ const installHtmlSupervisor = ({
|
|
|
467
652
|
copy.forEach(scriptToExecute => {
|
|
468
653
|
__html_supervisor__.addScriptToExecute(scriptToExecute);
|
|
469
654
|
});
|
|
655
|
+
window.addEventListener("error", errorEvent => {
|
|
656
|
+
if (!errorEvent.isTrusted) {
|
|
657
|
+
// ignore custom error event (not sent by browser)
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
const {
|
|
662
|
+
error
|
|
663
|
+
} = errorEvent;
|
|
664
|
+
displayErrorInDocument(error, {
|
|
665
|
+
rootDirectoryUrl,
|
|
666
|
+
url: errorEvent.filename,
|
|
667
|
+
line: errorEvent.lineno,
|
|
668
|
+
column: errorEvent.colno
|
|
669
|
+
});
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
if (window.__jsenv_event_source_client__) {
|
|
673
|
+
const onServerErrorEvent = serverErrorEvent => {
|
|
674
|
+
const {
|
|
675
|
+
reason,
|
|
676
|
+
stack,
|
|
677
|
+
url,
|
|
678
|
+
line,
|
|
679
|
+
column,
|
|
680
|
+
contentFrame
|
|
681
|
+
} = JSON.parse(serverErrorEvent.data);
|
|
682
|
+
displayErrorInDocument({
|
|
683
|
+
message: reason,
|
|
684
|
+
stack: stack ? `${stack}\n\n${contentFrame}` : contentFrame
|
|
685
|
+
}, {
|
|
686
|
+
rootDirectoryUrl,
|
|
687
|
+
url,
|
|
688
|
+
line,
|
|
689
|
+
column
|
|
690
|
+
});
|
|
691
|
+
};
|
|
692
|
+
|
|
693
|
+
window.__jsenv_event_source_client__.addEventCallbacks({
|
|
694
|
+
file_not_found: onServerErrorEvent,
|
|
695
|
+
parse_error: onServerErrorEvent,
|
|
696
|
+
unexpected_error: onServerErrorEvent
|
|
697
|
+
});
|
|
698
|
+
}
|
|
470
699
|
};
|
|
471
700
|
const superviseScriptTypeModule = ({
|
|
472
701
|
src,
|