@jsenv/core 27.5.2 → 27.6.1
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/dist/js/autoreload.js +7 -0
- package/dist/js/html_supervisor_installer.js +275 -154
- package/dist/main.js +171 -109
- package/package.json +2 -2
- package/src/dev/start_dev_server.js +4 -0
- package/src/omega/kitchen.js +13 -15
- package/src/omega/omega_server.js +4 -0
- package/src/omega/server/file_service.js +9 -66
- package/src/omega/url_graph/url_graph_load.js +0 -2
- package/src/omega/url_graph/url_info_transformations.js +27 -0
- package/src/omega/url_graph.js +1 -0
- package/src/plugins/autoreload/client/autoreload.js +7 -0
- package/src/plugins/html_supervisor/client/error_formatter.js +187 -67
- package/src/plugins/html_supervisor/client/error_overlay.js +29 -10
- package/src/plugins/html_supervisor/client/html_supervisor_installer.js +25 -73
- package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +94 -25
- package/src/test/execute_test_plan.js +1 -2
package/dist/js/autoreload.js
CHANGED
|
@@ -158,6 +158,7 @@ const reloader = {
|
|
|
158
158
|
isAutoreloadEnabled,
|
|
159
159
|
setAutoreloadPreference,
|
|
160
160
|
status: "idle",
|
|
161
|
+
currentExecution: null,
|
|
161
162
|
onstatuschange: () => {},
|
|
162
163
|
setStatus: status => {
|
|
163
164
|
reloader.status = status;
|
|
@@ -195,6 +196,7 @@ const reloader = {
|
|
|
195
196
|
const setReloadMessagePromise = (reloadMessage, promise) => {
|
|
196
197
|
promise.then(() => {
|
|
197
198
|
onApplied(reloadMessage);
|
|
199
|
+
reloader.currentExecution = null;
|
|
198
200
|
}, e => {
|
|
199
201
|
reloader.setStatus("failed");
|
|
200
202
|
|
|
@@ -206,6 +208,7 @@ const reloader = {
|
|
|
206
208
|
|
|
207
209
|
console.error(`[jsenv] Hot reload failed after ${reloadMessage.reason}.
|
|
208
210
|
This could be due to syntax errors or importing non-existent modules (see errors in console)`);
|
|
211
|
+
reloader.currentExecution = null;
|
|
209
212
|
});
|
|
210
213
|
};
|
|
211
214
|
|
|
@@ -299,6 +302,10 @@ const applyHotReload = async ({
|
|
|
299
302
|
}
|
|
300
303
|
|
|
301
304
|
console.log(`importing js module`);
|
|
305
|
+
reloader.currentExecution = {
|
|
306
|
+
type: "dynamic_import",
|
|
307
|
+
url: urlToFetch
|
|
308
|
+
};
|
|
302
309
|
const namespace = await reloadJsImport(urlToFetch);
|
|
303
310
|
|
|
304
311
|
if (urlHotMeta.acceptCallback) {
|
|
@@ -16,40 +16,76 @@ const formatError = (error, {
|
|
|
16
16
|
openInEditor,
|
|
17
17
|
url,
|
|
18
18
|
line,
|
|
19
|
-
column
|
|
20
|
-
codeFrame,
|
|
21
|
-
requestedRessource,
|
|
22
|
-
reportedBy
|
|
19
|
+
column
|
|
23
20
|
}) => {
|
|
24
21
|
let {
|
|
25
22
|
message,
|
|
26
23
|
stack
|
|
27
24
|
} = normalizeErrorParts(error);
|
|
28
|
-
let
|
|
25
|
+
let errorDetailsPromiseReference = {
|
|
29
26
|
current: null
|
|
30
27
|
};
|
|
31
|
-
let tip =
|
|
32
|
-
reportedBy,
|
|
33
|
-
requestedRessource
|
|
34
|
-
});
|
|
28
|
+
let tip = `Reported by the browser while executing <code>${window.location.pathname}${window.location.search}</code>.`;
|
|
35
29
|
let errorUrlSite;
|
|
30
|
+
const errorMeta = extractErrorMeta(error, {
|
|
31
|
+
url,
|
|
32
|
+
line,
|
|
33
|
+
column
|
|
34
|
+
});
|
|
36
35
|
|
|
37
36
|
const resolveUrlSite = ({
|
|
38
37
|
url,
|
|
39
38
|
line,
|
|
40
39
|
column
|
|
41
40
|
}) => {
|
|
42
|
-
|
|
41
|
+
if (typeof line === "string") line = parseInt(line);
|
|
42
|
+
if (typeof column === "string") column = parseInt(column);
|
|
43
|
+
const inlineUrlMatch = url.match(/@L([0-9]+)C([0-9]+)\-L([0-9]+)C([0-9]+)(\.[\w]+)$/);
|
|
43
44
|
|
|
44
45
|
if (inlineUrlMatch) {
|
|
45
46
|
const htmlUrl = url.slice(0, inlineUrlMatch.index);
|
|
46
|
-
const
|
|
47
|
-
const
|
|
47
|
+
const tagLineStart = parseInt(inlineUrlMatch[1]);
|
|
48
|
+
const tagColumnStart = parseInt(inlineUrlMatch[2]);
|
|
49
|
+
const tagLineEnd = parseInt(inlineUrlMatch[3]);
|
|
50
|
+
const tagColumnEnd = parseInt(inlineUrlMatch[4]);
|
|
51
|
+
const extension = inlineUrlMatch[5];
|
|
48
52
|
url = htmlUrl;
|
|
49
|
-
line =
|
|
50
|
-
|
|
53
|
+
line = tagLineStart + (typeof line === "number" ? line : 0); // stackTrace formatted by V8 (chrome)
|
|
54
|
+
|
|
55
|
+
if (Error.captureStackTrace) {
|
|
56
|
+
line--;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (errorMeta.type === "dynamic_import_syntax_error") {
|
|
60
|
+
// syntax error on inline script need line-1 for some reason
|
|
61
|
+
if (Error.captureStackTrace) {
|
|
62
|
+
line--;
|
|
63
|
+
} else {
|
|
64
|
+
// firefox and safari need line-2
|
|
65
|
+
line -= 2;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
column = tagColumnStart + (typeof column === "number" ? column : 0);
|
|
70
|
+
const fileUrl = resolveFileUrl(url);
|
|
71
|
+
return {
|
|
72
|
+
isInline: true,
|
|
73
|
+
originalUrl: `${fileUrl}@L${tagLineStart}C${tagColumnStart}-L${tagLineEnd}C${tagColumnEnd}${extension}`,
|
|
74
|
+
url: fileUrl,
|
|
75
|
+
line,
|
|
76
|
+
column
|
|
77
|
+
};
|
|
51
78
|
}
|
|
52
79
|
|
|
80
|
+
return {
|
|
81
|
+
isInline: false,
|
|
82
|
+
url: resolveFileUrl(url),
|
|
83
|
+
line,
|
|
84
|
+
column
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const resolveFileUrl = url => {
|
|
53
89
|
let urlObject = new URL(url);
|
|
54
90
|
|
|
55
91
|
if (urlObject.origin === window.origin) {
|
|
@@ -61,19 +97,11 @@ const formatError = (error, {
|
|
|
61
97
|
|
|
62
98
|
if (atFsIndex > -1) {
|
|
63
99
|
const afterAtFs = urlObject.pathname.slice(atFsIndex + "/@fs/".length);
|
|
64
|
-
|
|
65
|
-
} else {
|
|
66
|
-
url = urlObject.href;
|
|
100
|
+
return new URL(afterAtFs, "file:///").href;
|
|
67
101
|
}
|
|
68
|
-
} else {
|
|
69
|
-
url = urlObject.href;
|
|
70
102
|
}
|
|
71
103
|
|
|
72
|
-
return
|
|
73
|
-
url,
|
|
74
|
-
line,
|
|
75
|
-
column
|
|
76
|
-
};
|
|
104
|
+
return urlObject.href;
|
|
77
105
|
};
|
|
78
106
|
|
|
79
107
|
const generateClickableText = text => {
|
|
@@ -110,60 +138,179 @@ const formatError = (error, {
|
|
|
110
138
|
return textWithHtmlLinks;
|
|
111
139
|
};
|
|
112
140
|
|
|
113
|
-
const
|
|
114
|
-
|
|
141
|
+
const formatErrorText = ({
|
|
142
|
+
message,
|
|
143
|
+
stack,
|
|
144
|
+
codeFrame
|
|
145
|
+
}) => {
|
|
146
|
+
let text;
|
|
115
147
|
|
|
116
|
-
if (
|
|
117
|
-
|
|
148
|
+
if (message && stack) {
|
|
149
|
+
text = `${generateClickableText(message)}\n${generateClickableText(stack)}`;
|
|
150
|
+
} else if (stack) {
|
|
151
|
+
text = generateClickableText(stack);
|
|
152
|
+
} else {
|
|
153
|
+
text = generateClickableText(message);
|
|
118
154
|
}
|
|
119
155
|
|
|
120
|
-
if (
|
|
121
|
-
|
|
156
|
+
if (codeFrame) {
|
|
157
|
+
text += `\n\n${generateClickableText(codeFrame)}`;
|
|
122
158
|
}
|
|
123
159
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
160
|
+
return text;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const onErrorLocated = urlSite => {
|
|
164
|
+
errorUrlSite = urlSite;
|
|
165
|
+
|
|
166
|
+
errorDetailsPromiseReference.current = (async () => {
|
|
167
|
+
if (errorMeta.type === "dynamic_import_fetch_error") {
|
|
168
|
+
const response = await window.fetch(`/__get_error_cause__/${urlSite.isInline ? urlSite.originalUrl : urlSite.url}`);
|
|
169
|
+
|
|
170
|
+
if (response.status !== 200) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const causeInfo = await response.json();
|
|
175
|
+
|
|
176
|
+
if (!causeInfo) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const causeText = causeInfo.code === "NOT_FOUND" ? formatErrorText({
|
|
181
|
+
message: causeInfo.reason,
|
|
182
|
+
stack: causeInfo.codeFrame
|
|
183
|
+
}) : formatErrorText({
|
|
184
|
+
message: causeInfo.stack,
|
|
185
|
+
stack: causeInfo.codeFrame
|
|
186
|
+
});
|
|
187
|
+
return {
|
|
188
|
+
cause: causeText
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (urlSite.line !== undefined) {
|
|
193
|
+
let ressourceToFetch = `/__get_code_frame__/${formatUrlWithLineAndColumn(urlSite)}`;
|
|
194
|
+
|
|
195
|
+
if (!Error.captureStackTrace) {
|
|
196
|
+
ressourceToFetch += `?remap`;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const response = await window.fetch(ressourceToFetch);
|
|
200
|
+
const codeFrame = await response.text();
|
|
201
|
+
return {
|
|
202
|
+
codeFrame: formatErrorText({
|
|
203
|
+
message: codeFrame
|
|
204
|
+
})
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return null;
|
|
129
209
|
})();
|
|
130
210
|
}; // error.stack is more reliable than url/line/column reported on window error events
|
|
131
211
|
// so use it only when error.stack is not available
|
|
132
212
|
|
|
133
213
|
|
|
134
|
-
if (url && !stack)
|
|
214
|
+
if (url && !stack && // ignore window.reportError() it gives no valuable info
|
|
215
|
+
!url.endsWith("html_supervisor_installer.js")) {
|
|
135
216
|
onErrorLocated(resolveUrlSite({
|
|
136
217
|
url,
|
|
137
218
|
line,
|
|
138
219
|
column
|
|
139
220
|
}));
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
let text;
|
|
143
|
-
|
|
144
|
-
if (message && stack) {
|
|
145
|
-
text = `${generateClickableText(message)}\n${generateClickableText(stack)}`;
|
|
146
|
-
} else if (stack) {
|
|
147
|
-
text = generateClickableText(stack);
|
|
148
|
-
} else {
|
|
149
|
-
text = generateClickableText(message);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (codeFrame) {
|
|
153
|
-
text += `\n\n${generateClickableText(codeFrame)}`;
|
|
221
|
+
} else if (errorMeta.url) {
|
|
222
|
+
onErrorLocated(resolveUrlSite(errorMeta));
|
|
154
223
|
}
|
|
155
224
|
|
|
156
225
|
return {
|
|
157
226
|
theme: error && error.cause && error.cause.code === "PARSE_ERROR" ? "light" : "dark",
|
|
158
227
|
title: "An error occured",
|
|
159
|
-
text
|
|
160
|
-
|
|
228
|
+
text: formatErrorText({
|
|
229
|
+
message,
|
|
230
|
+
stack
|
|
231
|
+
}),
|
|
161
232
|
tip: `${tip}
|
|
162
233
|
<br />
|
|
163
|
-
Click outside to close
|
|
234
|
+
Click outside to close.`,
|
|
235
|
+
errorDetailsPromise: errorDetailsPromiseReference.current
|
|
164
236
|
};
|
|
165
237
|
};
|
|
166
238
|
|
|
239
|
+
const extractErrorMeta = (error, {
|
|
240
|
+
line
|
|
241
|
+
}) => {
|
|
242
|
+
if (!error) {
|
|
243
|
+
return {};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const {
|
|
247
|
+
message
|
|
248
|
+
} = error;
|
|
249
|
+
|
|
250
|
+
if (!message) {
|
|
251
|
+
return {};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
{
|
|
255
|
+
// chrome
|
|
256
|
+
if (message.includes("does not provide an export named")) {
|
|
257
|
+
return {
|
|
258
|
+
type: "dynamic_import_export_missing"
|
|
259
|
+
};
|
|
260
|
+
} // firefox
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
if (message.startsWith("import not found:")) {
|
|
264
|
+
return {
|
|
265
|
+
type: "dynamic_import_export_missing",
|
|
266
|
+
browser: "firefox"
|
|
267
|
+
};
|
|
268
|
+
} // safari
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
if (message.startsWith("import binding name")) {
|
|
272
|
+
return {
|
|
273
|
+
type: "dynamic_import_export_missing"
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
{
|
|
279
|
+
if (error.name === "SyntaxError" && typeof line === "number") {
|
|
280
|
+
return {
|
|
281
|
+
type: "dynamic_import_syntax_error"
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
{
|
|
287
|
+
// chrome
|
|
288
|
+
if (message.startsWith("Failed to fetch dynamically imported module: ")) {
|
|
289
|
+
const url = error.message.slice("Failed to fetch dynamically imported module: ".length);
|
|
290
|
+
return {
|
|
291
|
+
type: "dynamic_import_fetch_error",
|
|
292
|
+
url
|
|
293
|
+
};
|
|
294
|
+
} // firefox
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
if (message === "error loading dynamically imported module") {
|
|
298
|
+
return {
|
|
299
|
+
type: "dynamic_import_fetch_error"
|
|
300
|
+
};
|
|
301
|
+
} // safari
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
if (message === "Importing a module script failed.") {
|
|
305
|
+
return {
|
|
306
|
+
type: "dynamic_import_fetch_error"
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return {};
|
|
312
|
+
};
|
|
313
|
+
|
|
167
314
|
const formatUrlWithLineAndColumn = ({
|
|
168
315
|
url,
|
|
169
316
|
line,
|
|
@@ -250,17 +397,6 @@ const getErrorStackWithoutErrorMessage = error => {
|
|
|
250
397
|
return stack;
|
|
251
398
|
};
|
|
252
399
|
|
|
253
|
-
const formatTip = ({
|
|
254
|
-
reportedBy,
|
|
255
|
-
requestedRessource
|
|
256
|
-
}) => {
|
|
257
|
-
if (reportedBy === "browser") {
|
|
258
|
-
return `Reported by the browser while executing <code>${window.location.pathname}${window.location.search}</code>.`;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
return `Reported by the server while serving <code>${requestedRessource}</code>`;
|
|
262
|
-
};
|
|
263
|
-
|
|
264
400
|
const makeLinksClickable = (string, {
|
|
265
401
|
createLink = url => url
|
|
266
402
|
}) => {
|
|
@@ -365,16 +501,14 @@ const displayErrorInDocument = (error, {
|
|
|
365
501
|
url,
|
|
366
502
|
line,
|
|
367
503
|
column,
|
|
368
|
-
codeFrame
|
|
369
|
-
reportedBy,
|
|
370
|
-
requestedRessource
|
|
504
|
+
codeFrame
|
|
371
505
|
}) => {
|
|
372
506
|
const {
|
|
373
507
|
theme,
|
|
374
508
|
title,
|
|
375
509
|
text,
|
|
376
|
-
|
|
377
|
-
|
|
510
|
+
tip,
|
|
511
|
+
errorDetailsPromise
|
|
378
512
|
} = formatError(error, {
|
|
379
513
|
rootDirectoryUrl,
|
|
380
514
|
errorBaseUrl,
|
|
@@ -382,16 +516,14 @@ const displayErrorInDocument = (error, {
|
|
|
382
516
|
url,
|
|
383
517
|
line,
|
|
384
518
|
column,
|
|
385
|
-
codeFrame
|
|
386
|
-
reportedBy,
|
|
387
|
-
requestedRessource
|
|
519
|
+
codeFrame
|
|
388
520
|
});
|
|
389
521
|
let jsenvErrorOverlay = new JsenvErrorOverlay({
|
|
390
522
|
theme,
|
|
391
523
|
title,
|
|
392
524
|
text,
|
|
393
|
-
|
|
394
|
-
|
|
525
|
+
tip,
|
|
526
|
+
errorDetailsPromise
|
|
395
527
|
});
|
|
396
528
|
document.querySelectorAll(JSENV_ERROR_OVERLAY_TAGNAME).forEach(node => {
|
|
397
529
|
node.parentNode.removeChild(node);
|
|
@@ -421,8 +553,8 @@ class JsenvErrorOverlay extends HTMLElement {
|
|
|
421
553
|
theme,
|
|
422
554
|
title,
|
|
423
555
|
text,
|
|
424
|
-
|
|
425
|
-
|
|
556
|
+
tip,
|
|
557
|
+
errorDetailsPromise
|
|
426
558
|
}) {
|
|
427
559
|
super();
|
|
428
560
|
this.root = this.attachShadow({
|
|
@@ -453,17 +585,46 @@ class JsenvErrorOverlay extends HTMLElement {
|
|
|
453
585
|
this.parentNode.removeChild(this);
|
|
454
586
|
};
|
|
455
587
|
|
|
456
|
-
if (
|
|
457
|
-
|
|
458
|
-
if (this.parentNode) {
|
|
588
|
+
if (errorDetailsPromise) {
|
|
589
|
+
errorDetailsPromise.then(errorDetails => {
|
|
590
|
+
if (!errorDetails || !this.parentNode) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
const {
|
|
595
|
+
codeFrame,
|
|
596
|
+
cause
|
|
597
|
+
} = errorDetails;
|
|
598
|
+
|
|
599
|
+
if (codeFrame) {
|
|
459
600
|
this.root.querySelector(".text").innerHTML += `\n\n${codeFrame}`;
|
|
460
601
|
}
|
|
602
|
+
|
|
603
|
+
if (cause) {
|
|
604
|
+
const causeIndented = prefixRemainingLines(cause, " ");
|
|
605
|
+
this.root.querySelector(".text").innerHTML += `\n [cause]: ${causeIndented}`;
|
|
606
|
+
}
|
|
461
607
|
});
|
|
462
608
|
}
|
|
463
609
|
}
|
|
464
610
|
|
|
465
611
|
}
|
|
466
612
|
|
|
613
|
+
const prefixRemainingLines = (text, prefix) => {
|
|
614
|
+
const lines = text.split(/\r?\n/);
|
|
615
|
+
const firstLine = lines.shift();
|
|
616
|
+
let result = firstLine;
|
|
617
|
+
let i = 0;
|
|
618
|
+
|
|
619
|
+
while (i < lines.length) {
|
|
620
|
+
const line = lines[i];
|
|
621
|
+
i++;
|
|
622
|
+
result += line.length ? `\n${prefix}${line}` : `\n`;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
return result;
|
|
626
|
+
};
|
|
627
|
+
|
|
467
628
|
if (customElements && !customElements.get(JSENV_ERROR_OVERLAY_TAGNAME)) {
|
|
468
629
|
customElements.define(JSENV_ERROR_OVERLAY_TAGNAME, JsenvErrorOverlay);
|
|
469
630
|
}
|
|
@@ -665,14 +826,18 @@ const installHtmlSupervisor = ({
|
|
|
665
826
|
let completed;
|
|
666
827
|
let result;
|
|
667
828
|
let error;
|
|
829
|
+
const urlObject = new URL(src, window.location);
|
|
668
830
|
|
|
669
|
-
|
|
670
|
-
|
|
831
|
+
if (reload) {
|
|
832
|
+
urlObject.searchParams.set("hmr", Date.now());
|
|
833
|
+
}
|
|
671
834
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
835
|
+
__html_supervisor__.currentExecution = {
|
|
836
|
+
type: type === "module" ? "dynamic_import" : "script_injection",
|
|
837
|
+
url: urlObject.href
|
|
838
|
+
};
|
|
675
839
|
|
|
840
|
+
try {
|
|
676
841
|
result = await execute(urlObject.href);
|
|
677
842
|
completed = true;
|
|
678
843
|
} catch (e) {
|
|
@@ -693,6 +858,7 @@ const installHtmlSupervisor = ({
|
|
|
693
858
|
console.groupEnd();
|
|
694
859
|
}
|
|
695
860
|
|
|
861
|
+
__html_supervisor__.currentExecution = null;
|
|
696
862
|
return;
|
|
697
863
|
}
|
|
698
864
|
|
|
@@ -720,6 +886,8 @@ const installHtmlSupervisor = ({
|
|
|
720
886
|
if (logs) {
|
|
721
887
|
console.groupEnd();
|
|
722
888
|
}
|
|
889
|
+
|
|
890
|
+
__html_supervisor__.currentExecution = null;
|
|
723
891
|
};
|
|
724
892
|
|
|
725
893
|
const classicExecutionQueue = createExecutionQueue(performExecution);
|
|
@@ -808,6 +976,21 @@ const installHtmlSupervisor = ({
|
|
|
808
976
|
});
|
|
809
977
|
|
|
810
978
|
if (errorOverlay) {
|
|
979
|
+
const onErrorReportedByBrowser = (error, {
|
|
980
|
+
url,
|
|
981
|
+
line,
|
|
982
|
+
column
|
|
983
|
+
}) => {
|
|
984
|
+
displayErrorInDocument(error, {
|
|
985
|
+
rootDirectoryUrl,
|
|
986
|
+
errorBaseUrl,
|
|
987
|
+
openInEditor,
|
|
988
|
+
url,
|
|
989
|
+
line,
|
|
990
|
+
column
|
|
991
|
+
});
|
|
992
|
+
};
|
|
993
|
+
|
|
811
994
|
window.addEventListener("error", errorEvent => {
|
|
812
995
|
if (!errorEvent.isTrusted) {
|
|
813
996
|
// ignore custom error event (not sent by browser)
|
|
@@ -815,79 +998,17 @@ const installHtmlSupervisor = ({
|
|
|
815
998
|
}
|
|
816
999
|
|
|
817
1000
|
const {
|
|
818
|
-
error
|
|
1001
|
+
error,
|
|
1002
|
+
filename,
|
|
1003
|
+
lineno,
|
|
1004
|
+
colno
|
|
819
1005
|
} = errorEvent;
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
url: errorEvent.filename,
|
|
825
|
-
line: errorEvent.lineno,
|
|
826
|
-
column: errorEvent.colno,
|
|
827
|
-
reportedBy: "browser"
|
|
1006
|
+
onErrorReportedByBrowser(error, {
|
|
1007
|
+
url: filename,
|
|
1008
|
+
line: lineno,
|
|
1009
|
+
column: colno
|
|
828
1010
|
});
|
|
829
1011
|
});
|
|
830
|
-
|
|
831
|
-
if (window.__server_events__) {
|
|
832
|
-
const isExecuting = () => {
|
|
833
|
-
if (pendingExecutionCount > 0) {
|
|
834
|
-
return true;
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
if (document.readyState === "loading" || document.readyState === "interactive") {
|
|
838
|
-
return true;
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
if (window.__reloader__ && window.__reloader__.status === "reloading") {
|
|
842
|
-
return true;
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
return false;
|
|
846
|
-
};
|
|
847
|
-
|
|
848
|
-
window.__server_events__.addEventCallbacks({
|
|
849
|
-
error_while_serving_file: serverErrorEvent => {
|
|
850
|
-
if (!isExecuting()) {
|
|
851
|
-
return;
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
const {
|
|
855
|
-
message,
|
|
856
|
-
stack,
|
|
857
|
-
traceUrl,
|
|
858
|
-
traceLine,
|
|
859
|
-
traceColumn,
|
|
860
|
-
traceMessage,
|
|
861
|
-
requestedRessource,
|
|
862
|
-
isFaviconAutoRequest
|
|
863
|
-
} = JSON.parse(serverErrorEvent.data);
|
|
864
|
-
|
|
865
|
-
if (isFaviconAutoRequest) {
|
|
866
|
-
return;
|
|
867
|
-
} // setTimeout is to ensure the error
|
|
868
|
-
// dispatched on window by browser is displayed first,
|
|
869
|
-
// then the server error replaces it (because it contains more information)
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
setTimeout(() => {
|
|
873
|
-
displayErrorInDocument({
|
|
874
|
-
message,
|
|
875
|
-
stack
|
|
876
|
-
}, {
|
|
877
|
-
rootDirectoryUrl,
|
|
878
|
-
errorBaseUrl,
|
|
879
|
-
openInEditor,
|
|
880
|
-
url: traceUrl,
|
|
881
|
-
line: traceLine,
|
|
882
|
-
column: traceColumn,
|
|
883
|
-
codeFrame: traceMessage,
|
|
884
|
-
reportedBy: "server",
|
|
885
|
-
requestedRessource
|
|
886
|
-
});
|
|
887
|
-
}, 10);
|
|
888
|
-
}
|
|
889
|
-
});
|
|
890
|
-
}
|
|
891
1012
|
}
|
|
892
1013
|
};
|
|
893
1014
|
|