@jsenv/plugin-supervisor 1.4.0 → 1.4.2

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.
@@ -11,13 +11,17 @@ window.__supervisor__ = (() => {
11
11
  };
12
12
  const isWebkitOrSafari = typeof window.webkitConvertPointFromNodeToPage === "function";
13
13
  const executionResults = {};
14
- let documentExecutionStartTime;
14
+ let documentTimingsOrigin;
15
15
  try {
16
- documentExecutionStartTime = window.performance.timing.navigationStart;
16
+ documentTimingsOrigin = window.performance.timing.navigationStart;
17
17
  } catch (e) {
18
- documentExecutionStartTime = Date.now();
18
+ documentTimingsOrigin = Date.now();
19
19
  }
20
- let documentExecutionEndTime;
20
+ const documentTimings = {
21
+ origin: documentTimingsOrigin,
22
+ start: Date.now() - documentTimingsOrigin,
23
+ end: null
24
+ };
21
25
  supervisor.setup = ({
22
26
  rootDirectoryUrl,
23
27
  scriptInfos,
@@ -76,10 +80,13 @@ window.__supervisor__ = (() => {
76
80
  const createExecutionController = (src, type) => {
77
81
  const result = {
78
82
  status: "pending",
79
- duration: null,
80
83
  coverage: null,
81
84
  exception: null,
82
- value: null
85
+ value: null,
86
+ timings: {
87
+ start: null,
88
+ end: null
89
+ }
83
90
  };
84
91
  let resolve;
85
92
  const promise = new Promise(_resolve => {
@@ -88,7 +95,7 @@ window.__supervisor__ = (() => {
88
95
  promises.push(promise);
89
96
  executionResults[src] = result;
90
97
  const start = () => {
91
- result.duration = null;
98
+ result.timings.start = Date.now() - documentTimingsOrigin;
92
99
  result.coverage = null;
93
100
  result.status = "started";
94
101
  result.exception = null;
@@ -97,16 +104,15 @@ window.__supervisor__ = (() => {
97
104
  }
98
105
  };
99
106
  const end = () => {
100
- const now = Date.now();
101
107
  remainingScriptCount--;
102
- result.duration = now - documentExecutionStartTime;
108
+ result.timings.end = Date.now() - documentTimingsOrigin;
103
109
  result.coverage = window.__coverage__;
104
110
  if (logs) {
105
111
  console.log("execution ".concat(result.status));
106
112
  console.groupEnd();
107
113
  }
108
114
  if (remainingScriptCount === 0) {
109
- documentExecutionEndTime = now;
115
+ documentTimings.end = Date.now() - documentTimingsOrigin;
110
116
  }
111
117
  resolve();
112
118
  };
@@ -163,17 +169,27 @@ window.__supervisor__ = (() => {
163
169
  const {
164
170
  detectedBy,
165
171
  failed,
166
- error
172
+ errorEvent
167
173
  } = await scriptLoadPromise;
168
174
  if (failed) {
175
+ const messageDefault = "Error while loading script";
176
+ const {
177
+ error,
178
+ message,
179
+ filename,
180
+ lineno,
181
+ colno
182
+ } = errorEvent;
169
183
  if (detectedBy === "script_error_event") {
170
184
  // window.error won't be dispatched for this error
171
- reportErrorBackToBrowser(error);
185
+ reportErrorBackToBrowser(error || errorEvent);
172
186
  }
173
- fail(error, {
174
- message: "Error while loading script: ".concat(urlObject.href),
187
+ fail(error || message || messageDefault, {
188
+ message: messageDefault,
175
189
  reportedBy: "script_error_event",
176
- url: urlObject.href
190
+ url: filename || urlObject.href,
191
+ line: lineno,
192
+ column: colno
177
193
  });
178
194
  if (detectedBy === "script_error_event") {
179
195
  supervisor.reportException(result.exception);
@@ -236,7 +252,7 @@ window.__supervisor__ = (() => {
236
252
  return result;
237
253
  } catch (e) {
238
254
  fail(e, {
239
- message: "Error while importing module: ".concat(urlObject.href),
255
+ message: "Error while importing module",
240
256
  reportedBy: "dynamic_import",
241
257
  url: urlObject.href
242
258
  });
@@ -289,16 +305,26 @@ window.__supervisor__ = (() => {
289
305
  const {
290
306
  detectedBy,
291
307
  failed,
292
- error
308
+ errorEvent
293
309
  } = await scriptLoadResultPromise;
294
310
  if (failed) {
311
+ const messageDefault = "Error while loading module";
312
+ const {
313
+ error,
314
+ message,
315
+ filename,
316
+ lineno,
317
+ colno
318
+ } = errorEvent;
295
319
  // if (detectedBy === "script_error_event") {
296
320
  // reportErrorBackToBrowser(error)
297
321
  // }
298
- fail(error, {
299
- message: "Error while loading module: ".concat(urlObject.href),
322
+ fail(error || message || messageDefault, {
323
+ message: messageDefault,
300
324
  reportedBy: "script_error_event",
301
- url: urlObject.href
325
+ url: filename || urlObject.href,
326
+ line: lineno,
327
+ column: colno
302
328
  });
303
329
  if (detectedBy === "script_error_event") {
304
330
  supervisor.reportException(result.exception);
@@ -420,8 +446,7 @@ window.__supervisor__ = (() => {
420
446
  supervisor.getDocumentExecutionResult = async () => {
421
447
  await Promise.all(promises);
422
448
  return {
423
- startTime: documentExecutionStartTime,
424
- endTime: documentExecutionEndTime,
449
+ timings: documentTimings,
425
450
  status: "completed",
426
451
  executionResults
427
452
  };
@@ -471,10 +496,11 @@ window.__supervisor__ = (() => {
471
496
  // the stack from runtime, not normalized to v8
472
497
  stackTrace: "",
473
498
  // the stack trace (without error name and message)
499
+ stackFrames: undefined,
474
500
  withServerUrls: {
475
501
  message: "",
476
- stackTrace: "",
477
- stack: ""
502
+ stack: "",
503
+ stackTrace: ""
478
504
  },
479
505
  meta: null,
480
506
  site: {
@@ -498,76 +524,140 @@ window.__supervisor__ = (() => {
498
524
  exception.message = reason;
499
525
  return;
500
526
  }
501
- if (reason instanceof Error) {
502
- const error = reason;
503
- exception.isError = true;
504
- exception.name = error.name || "Error";
505
- exception.message = error.message || "";
506
- if (Error.captureStackTrace &&
507
- // captureStackTrace exists on webkit but error.stack is not v8
508
- !isWebkitOrSafari) {
509
- // stackTrace formatted by V8
510
- exception.stackSourcemapped = true;
511
- exception.stack = error.stack;
512
- exception.stackTrace = getErrorStackTrace(error);
513
- } else if (error.stack) {
514
- exception.stackSourcemapped = false;
515
- exception.stackTrace = error.stack;
516
- exception.stack = stringifyStack(exception);
517
- }
518
- if (error.reportedBy) {
519
- exception.reportedBy = error.reportedBy;
520
- }
521
- if (error.url) {
522
- Object.assign(exception.site, resolveUrlSite({
523
- url: error.url
524
- }));
525
- }
526
- {
527
- // chrome
528
- if (error.message.includes("does not provide an export named")) {
529
- exception.code = DYNAMIC_IMPORT_EXPORT_MISSING;
530
- return;
531
- }
532
- // firefox
533
- if (error.message.startsWith("import not found:") || error.message.startsWith("ambiguous indirect export:")) {
534
- exception.code = DYNAMIC_IMPORT_EXPORT_MISSING;
535
- return;
527
+ if (typeof reason !== "object") {
528
+ exception.message = JSON.stringify(reason);
529
+ return;
530
+ }
531
+ // isError can be false when reason is an ErrorEvent for instance
532
+ exception.isError = reason instanceof Error;
533
+ exception.name = reason.name || "Error";
534
+ exception.message = reason.message || message || "";
535
+ let stackFrames;
536
+ if (exception.isError && Error.captureStackTrace &&
537
+ // captureStackTrace exists on webkit but error.stack is not v8
538
+ !isWebkitOrSafari) {
539
+ // stackTrace formatted by V8
540
+ const {
541
+ prepareStackTrace
542
+ } = Error;
543
+ Error.prepareStackTrace = (e, callSites) => {
544
+ Error.prepareStackTrace = prepareStackTrace;
545
+ const getPropertiesFromEvalOrigin = origin => {
546
+ // Most eval() calls are in this format
547
+ const topLevelEvalMatch = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
548
+ if (topLevelEvalMatch) {
549
+ const source = topLevelEvalMatch[2];
550
+ const line = Number(topLevelEvalMatch[3]);
551
+ const column = topLevelEvalMatch[4] - 1;
552
+ return {
553
+ url: source,
554
+ line,
555
+ column
556
+ };
557
+ }
558
+ // Parse nested eval() calls using recursion
559
+ const nestedEvalMatch = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
560
+ if (nestedEvalMatch) {
561
+ return getPropertiesFromEvalOrigin(nestedEvalMatch[2]);
562
+ }
563
+ return null;
564
+ };
565
+ stackFrames = [];
566
+ for (const callSite of callSites) {
567
+ const url = callSite.getFileName() || callSite.getScriptNameOrSourceURL();
568
+ const line = callSite.getLineNumber();
569
+ const column = callSite.getColumnNumber();
570
+ const site = resolveUrlSite({
571
+ url,
572
+ line,
573
+ column
574
+ });
575
+ const stackFrame = {
576
+ raw: " at ".concat(String(callSite)),
577
+ url: site.url,
578
+ line: site.line,
579
+ column: site.column,
580
+ functionName: callSite.getFunctionName(),
581
+ isNative: callSite.isNative(),
582
+ isEval: callSite.isEval(),
583
+ isConstructor: callSite.isConstructor(),
584
+ isAsync: callSite.isAsync(),
585
+ evalSite: null
586
+ };
587
+ if (stackFrame.isEval) {
588
+ const evalOrigin = stackFrame.getEvalOrigin();
589
+ if (evalOrigin) {
590
+ stackFrame.evalSite = getPropertiesFromEvalOrigin(evalOrigin);
591
+ }
592
+ }
593
+ stackFrames.push(stackFrame);
536
594
  }
537
- // safari
538
- if (error.message.startsWith("import binding name")) {
539
- exception.code = DYNAMIC_IMPORT_EXPORT_MISSING;
540
- return;
595
+ let stackTrace = "";
596
+ for (const stackFrame of stackFrames) {
597
+ if (stackTrace) stackTrace += "\n";
598
+ stackTrace += stackFrame.raw;
541
599
  }
542
- if (error.message.includes("Importing a module script failed")) {
543
- exception.code = DYNAMIC_IMPORT_FETCH_ERROR;
544
- return;
600
+ exception.stackTrace = stackTrace;
601
+ let stack = "";
602
+ const name = reason.name || "Error";
603
+ const message = reason.message || "";
604
+ stack += "".concat(name, ": ").concat(message);
605
+ if (stackTrace) {
606
+ stack += "\n".concat(stackTrace);
545
607
  }
546
- }
547
- {
548
- if (error.name === "SyntaxError" && typeof line === "number") {
549
- exception.code = DYNAMIC_IMPORT_SYNTAX_ERROR;
550
- return;
608
+ return stack;
609
+ };
610
+ exception.stackSourcemapped = true;
611
+ exception.stack = reason.stack;
612
+ if (stackFrames === undefined) {
613
+ // Error.prepareStackTrace not trigerred
614
+ // - reason is not an error
615
+ // - reason.stack already get
616
+ Error.prepareStackTrace = prepareStackTrace;
617
+ exception.stackTrace = getErrorStackTrace(reason);
618
+ } else {
619
+ exception.stackFrames = stackFrames;
620
+ const [firstCallFrame] = stackFrames;
621
+ if (exception.site.url === null && firstCallFrame && firstCallFrame.url) {
622
+ Object.assign(exception.site, {
623
+ url: firstCallFrame.url,
624
+ line: firstCallFrame.line,
625
+ column: firstCallFrame.column
626
+ });
551
627
  }
552
628
  }
553
- return;
629
+ } else {
630
+ exception.stackSourcemapped = false;
631
+ exception.stackTrace = reason.stack;
632
+ exception.stack = stringifyStack(exception);
554
633
  }
555
- if (typeof reason === "object") {
556
- // happens when reason is an Event for instance
557
- exception.code = reason.code;
558
- exception.message = reason.message || message;
559
- exception.stack = reason.stack;
560
- if (reason.reportedBy) {
561
- exception.reportedBy = reason.reportedBy;
634
+ if (exception.site.url === null && reason.url) {
635
+ Object.assign(exception.site, resolveUrlSite({
636
+ url: reason.url
637
+ }));
638
+ }
639
+ {
640
+ // chrome
641
+ if (exception.message.includes("does not provide an export named")) {
642
+ exception.code = DYNAMIC_IMPORT_EXPORT_MISSING;
562
643
  }
563
- if (reason.url) {
564
- Object.assign(exception.site, resolveUrlSite({
565
- url: reason.url
566
- }));
644
+ // firefox
645
+ if (exception.message.startsWith("import not found:") || exception.message.startsWith("ambiguous indirect export:")) {
646
+ exception.code = DYNAMIC_IMPORT_EXPORT_MISSING;
647
+ }
648
+ // safari
649
+ if (exception.message.startsWith("import binding name")) {
650
+ exception.code = DYNAMIC_IMPORT_EXPORT_MISSING;
651
+ }
652
+ if (exception.message.includes("Importing a module script failed")) {
653
+ exception.code = DYNAMIC_IMPORT_FETCH_ERROR;
654
+ }
655
+ }
656
+ {
657
+ if (!exception.code && exception.name === "SyntaxError" && typeof line === "number") {
658
+ exception.code = DYNAMIC_IMPORT_SYNTAX_ERROR;
567
659
  }
568
- return;
569
660
  }
570
- exception.message = JSON.stringify(reason);
571
661
  };
572
662
  writeBasicProperties();
573
663
 
@@ -584,7 +674,7 @@ window.__supervisor__ = (() => {
584
674
  line,
585
675
  column
586
676
  });
587
- if (fileUrlSite.isInline && exception.code === DYNAMIC_IMPORT_SYNTAX_ERROR) {
677
+ if (fileUrlSite.isInline && exception.name === "SyntaxError" && exception.code !== DYNAMIC_IMPORT_EXPORT_MISSING) {
588
678
  // syntax error on inline script need line-1 for some reason
589
679
  fileUrlSite.line = fileUrlSite.line - 1;
590
680
  }
@@ -617,17 +707,19 @@ window.__supervisor__ = (() => {
617
707
  return exception;
618
708
  };
619
709
  const stringifyStack = ({
710
+ codeFrame,
620
711
  name,
621
712
  message,
622
713
  stackTrace
623
714
  }) => {
624
- let stack;
715
+ let stack = "";
716
+ if (codeFrame) {
717
+ stack += "".concat(codeFrame, "\n");
718
+ }
625
719
  if (name && message) {
626
- stack = "".concat(name, ": ").concat(message);
720
+ stack += "".concat(name, ": ").concat(message);
627
721
  } else if (message) {
628
- stack = message;
629
- } else {
630
- stack = "";
722
+ stack += message;
631
723
  }
632
724
  if (stackTrace) {
633
725
  stack += "\n".concat(stackTrace);
@@ -764,140 +856,6 @@ window.__supervisor__ = (() => {
764
856
  return replacement;
765
857
  });
766
858
  };
767
- let formatError;
768
- {
769
- formatError = exceptionInfo => {
770
- const errorParts = {
771
- theme: "dark",
772
- title: "An error occured",
773
- text: "",
774
- tip: "",
775
- errorDetailsPromise: null
776
- };
777
- const tips = [];
778
- tips.push("Click outside to close.");
779
- errorParts.tip = tips.join("\n <br />\n ");
780
- const generateClickableText = text => {
781
- const textWithHtmlLinks = makeLinksClickable(text, {
782
- createLink: ({
783
- url,
784
- line,
785
- column
786
- }) => {
787
- const urlSite = resolveUrlSite({
788
- url,
789
- line,
790
- column
791
- });
792
- if (errorBaseUrl) {
793
- if (urlSite.url.startsWith(rootDirectoryUrl)) {
794
- urlSite.url = "".concat(errorBaseUrl).concat(urlSite.url.slice(rootDirectoryUrl.length));
795
- } else {
796
- urlSite.url = "file:///mocked_for_snapshots";
797
- }
798
- }
799
- const urlWithLineAndColumn = stringifyUrlSite(urlSite);
800
- return {
801
- href: urlSite.url.startsWith("file:") && openInEditor ? "javascript:window.fetch('/__open_in_editor__/".concat(encodeURIComponent(urlWithLineAndColumn), "')") : urlSite.url,
802
- text: urlWithLineAndColumn
803
- };
804
- }
805
- });
806
- return textWithHtmlLinks;
807
- };
808
- errorParts.text = stringifyStack({
809
- name: exceptionInfo.name,
810
- message: exceptionInfo.message ? generateClickableText(exceptionInfo.message) : "",
811
- stackTrace: exceptionInfo.stackTrace ? generateClickableText(exceptionInfo.stackTrace) : ""
812
- });
813
- if (exceptionInfo.site.url) {
814
- errorParts.errorDetailsPromise = (async () => {
815
- if (!serverIsJsenvDevServer) {
816
- return null;
817
- }
818
- try {
819
- if (exceptionInfo.code === DYNAMIC_IMPORT_FETCH_ERROR || exceptionInfo.reportedBy === "script_error_event") {
820
- const response = await window.fetch("/__get_error_cause__/".concat(encodeURIComponent(exceptionInfo.site.isInline ? exceptionInfo.site.originalUrl : exceptionInfo.site.url)));
821
- if (response.status !== 200) {
822
- return null;
823
- }
824
- const causeInfo = await response.json();
825
- if (!causeInfo) {
826
- return null;
827
- }
828
- const causeText = causeInfo.code === "NOT_FOUND" ? stringifyStack({
829
- name: causeInfo.name,
830
- message: generateClickableText(causeInfo.reason),
831
- stackTrace: generateClickableText(causeInfo.codeFrame)
832
- }) : stringifyStack({
833
- name: causeInfo.name,
834
- message: generateClickableText(causeInfo.stack),
835
- stackTrace: generateClickableText(causeInfo.codeFrame)
836
- });
837
- return {
838
- cause: causeText
839
- };
840
- }
841
- if (exceptionInfo.site.line !== undefined) {
842
- const urlToFetch = new URL("/__get_code_frame__/".concat(encodeURIComponent(stringifyUrlSite(exceptionInfo.site))), window.origin);
843
- if (!exceptionInfo.stackSourcemapped) {
844
- urlToFetch.searchParams.set("remap", "");
845
- }
846
- const response = await window.fetch(urlToFetch);
847
- if (response.status !== 200) {
848
- return null;
849
- }
850
- const codeFrame = await response.text();
851
- return {
852
- codeFrame: generateClickableText(codeFrame)
853
- };
854
- }
855
- } catch (e) {
856
- // happens if server is closed for instance
857
- return null;
858
- }
859
- return null;
860
- })();
861
- }
862
- return errorParts;
863
- };
864
- const makeLinksClickable = (string, {
865
- createLink = ({
866
- url
867
- }) => url
868
- }) => {
869
- // normalize line breaks
870
- string = string.replace(/\n/g, "\n");
871
- string = escapeHtml(string);
872
- // render links
873
- string = replaceUrls(string, ({
874
- url,
875
- line,
876
- column
877
- }) => {
878
- const {
879
- href,
880
- text
881
- } = createLink({
882
- url,
883
- line,
884
- column
885
- });
886
- return link({
887
- href,
888
- text
889
- });
890
- });
891
- return string;
892
- };
893
- const escapeHtml = string => {
894
- return string.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
895
- };
896
- const link = ({
897
- href,
898
- text = href
899
- }) => "<a href=\"".concat(href, "\">").concat(text, "</a>");
900
- }
901
859
  let displayErrorNotification;
902
860
  {
903
861
  const {
@@ -941,46 +899,151 @@ window.__supervisor__ = (() => {
941
899
  return removeErrorOverlay;
942
900
  };
943
901
  class JsenvErrorOverlay extends HTMLElement {
944
- constructor({
945
- theme,
946
- title,
947
- text,
948
- tip,
949
- errorDetailsPromise
950
- }) {
902
+ constructor(exception) {
951
903
  super();
952
- this.root = this.attachShadow({
904
+ const root = this.attachShadow({
953
905
  mode: "open"
954
906
  });
955
- this.root.innerHTML = "\n<style>\n ".concat(overlayCSS, "\n</style>\n<div class=\"backdrop\"></div>\n<div class=\"overlay\" data-theme=").concat(theme, ">\n <h1 class=\"title\">\n ").concat(title, "\n </h1>\n <pre class=\"text\">").concat(text, "</pre>\n <div class=\"tip\">\n ").concat(tip, "\n </div>\n</div>");
956
- this.root.querySelector(".backdrop").onclick = () => {
907
+ const tips = [];
908
+ tips.push("Click outside to close.");
909
+ const tip = tips.join("\n <br />\n ");
910
+ root.innerHTML = "\n<style>\n ".concat(overlayCSS, "\n</style>\n<div class=\"backdrop\"></div>\n<div class=\"overlay\" data-theme=\"dark\">\n <h1 class=\"title\">\n An error occured\n </h1>\n <pre class=\"text\"></pre>\n <div class=\"tip\">\n ").concat(tip, "\n </div>\n</div>");
911
+ root.querySelector(".backdrop").onclick = () => {
957
912
  if (!this.parentNode) {
958
913
  // not in document anymore
959
914
  return;
960
915
  }
961
- this.root.querySelector(".backdrop").onclick = null;
916
+ root.querySelector(".backdrop").onclick = null;
962
917
  this.parentNode.removeChild(this);
963
918
  };
964
- if (errorDetailsPromise) {
965
- errorDetailsPromise.then(errorDetails => {
966
- if (!errorDetails || !this.parentNode) {
967
- return;
919
+ const renderException = () => {
920
+ const {
921
+ cause = {}
922
+ } = exception;
923
+ const {
924
+ trace = {}
925
+ } = cause;
926
+ root.querySelector(".text").innerHTML = stringifyStack({
927
+ codeFrame: trace.codeFrame ? generateClickableText(trace.codeFrame) : "",
928
+ name: exception.name,
929
+ message: exception.message ? generateClickableText(exception.message) : "",
930
+ stackTrace: exception.stackTrace ? generateClickableText(exception.stackTrace) : ""
931
+ });
932
+ if (cause) {
933
+ const causeText = stringifyStack({
934
+ name: cause.name,
935
+ message: cause.reason ? generateClickableText(cause.reason) : cause.stack ? generateClickableText(cause.stack) : ""
936
+ });
937
+ if (causeText) {
938
+ const causeTextIndented = prefixRemainingLines(causeText, " ");
939
+ root.querySelector(".text").innerHTML += "\n [cause]: ".concat(causeTextIndented);
968
940
  }
969
- const {
970
- codeFrame,
971
- cause
972
- } = errorDetails;
973
- if (codeFrame) {
974
- this.root.querySelector(".text").innerHTML += "\n\n".concat(codeFrame);
941
+ }
942
+ if (!exception.stackTrace && (exception.reportedBy === "script_error_event" || exception.reportedBy === "window_error_event" || exception.name === "SyntaxError" || exception.code === DYNAMIC_IMPORT_FETCH_ERROR || exception.code === DYNAMIC_IMPORT_EXPORT_MISSING || exception.code === DYNAMIC_IMPORT_SYNTAX_ERROR)) {
943
+ let traceSite = stringifyUrlSite(trace);
944
+ if (traceSite) {
945
+ root.querySelector(".text").innerHTML += "\n at ".concat(generateClickableText(traceSite));
975
946
  }
976
- if (cause) {
977
- const causeIndented = prefixRemainingLines(cause, " ");
978
- this.root.querySelector(".text").innerHTML += "\n [cause]: ".concat(causeIndented);
947
+ }
948
+ };
949
+ renderException();
950
+ if (exception.site.url && serverIsJsenvDevServer) {
951
+ (async () => {
952
+ try {
953
+ if (exception.code === DYNAMIC_IMPORT_FETCH_ERROR || exception.reportedBy === "script_error_event") {
954
+ const response = await window.fetch("/__get_error_cause__/".concat(encodeURIComponent(exception.site.isInline ? exception.site.originalUrl : exception.site.url)));
955
+ if (response.status !== 200) {
956
+ return;
957
+ }
958
+ const causeInfo = await response.json();
959
+ if (!causeInfo) {
960
+ return;
961
+ }
962
+ exception.cause = causeInfo;
963
+ renderException();
964
+ return;
965
+ }
966
+ if (exception.site.line !== undefined) {
967
+ const urlToFetch = new URL("/__get_cause_trace__/".concat(encodeURIComponent(stringifyUrlSite(exception.site))), window.origin);
968
+ if (!exception.stackSourcemapped) {
969
+ urlToFetch.searchParams.set("remap", "");
970
+ }
971
+ const response = await window.fetch(urlToFetch);
972
+ if (response.status !== 200) {
973
+ return;
974
+ }
975
+ const causeTrace = await response.json();
976
+ exception.cause = {
977
+ trace: causeTrace
978
+ };
979
+ renderException();
980
+ return;
981
+ }
982
+ } catch (e) {
983
+ // happens if server is closed for instance
984
+ return;
979
985
  }
980
- });
986
+ })();
981
987
  }
982
988
  }
983
989
  }
990
+ const generateClickableText = text => {
991
+ const textWithHtmlLinks = makeLinksClickable(text, {
992
+ createLink: ({
993
+ url,
994
+ line,
995
+ column
996
+ }) => {
997
+ const urlSite = resolveUrlSite({
998
+ url,
999
+ line,
1000
+ column
1001
+ });
1002
+ if (errorBaseUrl) {
1003
+ if (urlSite.url.startsWith(rootDirectoryUrl)) {
1004
+ urlSite.url = "".concat(errorBaseUrl).concat(urlSite.url.slice(rootDirectoryUrl.length));
1005
+ } else {
1006
+ urlSite.url = "file:///mocked_for_snapshots";
1007
+ }
1008
+ }
1009
+ const urlWithLineAndColumn = stringifyUrlSite(urlSite);
1010
+ return {
1011
+ href: urlSite.url.startsWith("file:") && openInEditor ? "javascript:window.fetch('/__open_in_editor__/".concat(encodeURIComponent(urlWithLineAndColumn), "')") : urlSite.url,
1012
+ text: urlWithLineAndColumn
1013
+ };
1014
+ }
1015
+ });
1016
+ return textWithHtmlLinks;
1017
+ };
1018
+ const makeLinksClickable = (string, {
1019
+ createLink = ({
1020
+ url
1021
+ }) => url
1022
+ }) => {
1023
+ // normalize line breaks
1024
+ string = string.replace(/\r\n/g, "\n");
1025
+ string = escapeHtml(string);
1026
+ // render links
1027
+ string = replaceUrls(string, ({
1028
+ url,
1029
+ line,
1030
+ column
1031
+ }) => {
1032
+ const {
1033
+ href,
1034
+ text
1035
+ } = createLink({
1036
+ url,
1037
+ line,
1038
+ column
1039
+ });
1040
+ return link({
1041
+ href,
1042
+ text
1043
+ });
1044
+ });
1045
+ return string;
1046
+ };
984
1047
  const prefixRemainingLines = (text, prefix) => {
985
1048
  const lines = text.split(/\r?\n/);
986
1049
  const firstLine = lines.shift();
@@ -993,6 +1056,13 @@ window.__supervisor__ = (() => {
993
1056
  }
994
1057
  return result;
995
1058
  };
1059
+ const escapeHtml = string => {
1060
+ return string.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
1061
+ };
1062
+ const link = ({
1063
+ href,
1064
+ text = href
1065
+ }) => "<a href=\"".concat(href, "\">").concat(text, "</a>");
996
1066
  if (customElements && !customElements.get(JSENV_ERROR_OVERLAY_TAGNAME)) {
997
1067
  customElements.define(JSENV_ERROR_OVERLAY_TAGNAME, JsenvErrorOverlay);
998
1068
  }
@@ -1000,21 +1070,8 @@ window.__supervisor__ = (() => {
1000
1070
  }
1001
1071
  supervisor.createException = createException;
1002
1072
  supervisor.reportException = exception => {
1003
- const {
1004
- theme,
1005
- title,
1006
- text,
1007
- tip,
1008
- errorDetailsPromise
1009
- } = formatError(exception);
1010
1073
  if (errorOverlay) {
1011
- const removeErrorOverlay = displayJsenvErrorOverlay({
1012
- theme,
1013
- title,
1014
- text,
1015
- tip,
1016
- errorDetailsPromise
1017
- });
1074
+ const removeErrorOverlay = displayJsenvErrorOverlay(exception);
1018
1075
  if (window.__reloader__) {
1019
1076
  const onchange = window.__reloader__.status.onchange;
1020
1077
  window.__reloader__.status.onchange = () => {
@@ -1027,8 +1084,8 @@ window.__supervisor__ = (() => {
1027
1084
  }
1028
1085
  if (errorNotification) {
1029
1086
  displayErrorNotification({
1030
- title,
1031
- text
1087
+ title: "An error occured",
1088
+ text: "todo"
1032
1089
  });
1033
1090
  }
1034
1091
  return exception;
@@ -1055,6 +1112,7 @@ window.__supervisor__ = (() => {
1055
1112
  // when error is reported within a worker error is null
1056
1113
  // but there is a message property on errorEvent
1057
1114
  reportedBy: "window_error_event",
1115
+ message,
1058
1116
  url: filename,
1059
1117
  line: lineno,
1060
1118
  column: colno
@@ -1097,7 +1155,7 @@ window.__supervisor__ = (() => {
1097
1155
  resolve({
1098
1156
  detectedBy: "window_error_event",
1099
1157
  failed: true,
1100
- error: errorEvent
1158
+ errorEvent
1101
1159
  });
1102
1160
  }
1103
1161
  };
@@ -1110,7 +1168,7 @@ window.__supervisor__ = (() => {
1110
1168
  resolve({
1111
1169
  detectedBy: "script_error_event",
1112
1170
  failed: true,
1113
- error: errorEvent
1171
+ errorEvent
1114
1172
  });
1115
1173
  });
1116
1174
  script.addEventListener("load", () => {