skip to Main Content

(I initially thought this was just a Chrome bug, but I’ve tested in Firefox and it has similar weird behavior, and even uses the exact same "Script error." string in the event.message, so I’m wondering whether this is a spec-related issue.)

My intuition with the code below is of course that each of the tests (where I purposely input an invalid value into a constructor) should produce the same ErrorEvent (just with different line numbers and stuff) in the window.addEventListener("error", ...) handler, but as noted in the comments of this code block, they produce different behavior.

<script>
  window.addEventListener("error", function(e) {
    console.error("window error handler:", e);
  })
</script>

<!-- Note: This is just an immutable snapshot of https://codemirror.net/codemirror.js and note that the txt extension doesn't affect this issue - it occurs with js extension too. The txt was just because github doesn't allow uploading js files. -->
<script src="https://github.com/user-attachments/files/17729754/codemirror6-november-13-2024.txt"></script>

<script>
  let { EditorView } = CM["@codemirror/view"];
</script>

<script>
  new EditorView(null); // Example 1: just "Script error."
</script>

<script type="module">
  new EditorView(null); // Example 2: just "Script error."
</script>

<script type="module">
  await new Promise(r => setTimeout(r, 10));
  new EditorView(null); // Example 3: just "Script error."
</script>

<script>
  (async function() {
    new EditorView(null); // Example 4: no window error event at all??
  })();
</script>

<script type="module">
  let { EditorView } = await import("https://esm.sh/@codemirror/[email protected]");
  new EditorView(null); // Example 5: ✅ produces error event with the actual error attached 
</script>


<!-- note: this uses a data url, but i tested using an actual server to server this file and it's the same result -->
<script src="data:text/plain,window.foo=function(a){a.b.c}"></script>
<script>
  foo(1); // Example 6: ✅ produces error event with the actual error attached 
  // caveat: in firefox, specifically, this data URL version gives "Script error.", but substituting it with a server url version results in the same behavior as chrome.
  // chrome gives the 'correct' behavior for both cases.
</script>

Notes:

  • I initially thought it had something to do with module scripts, but the last example shows that’s not the cause.
  • I thought maybe Example 4 had something to do with needing a window.addEventListener("unhandledrejection", ...) handler, but I tried that and it didn’t receive any events.
  • The ErrorEvent also includes the filename property, which gives the script that caused it (but includes no line number, stack, etc.)

Extra Context:

I’m building a developer tool which hooks into the error events on the page to help the developer understand the cause/source of the error. I don’t control the code on the page, so I need to be able to get the error details without re-writing the code.

Hence "you could just avoid writing your code/imports in XYZ form" is unfortunately not a solution for me.

Addendum:

(Bolding is for skimming, not shouting.)

  • This SO question/answer seems to suggest that it’s due to a security consideration when loading cross-domain scripts. But, strangely, @KLASANGUI’s answer shows that the error messages can be accessed if the defer attribute is added to the script even though the github.com script in my example doesn’t have the appropriate CORS headers (so it can’t be that defer just uses crossorigin by default).

2

Answers


  1. Please, note that you must attach the event listeners before any other script runs, defer the others scripts so they run after the initializer (not in parallel).

    Also, note that error events have error objects that are the original error (with the proper stack if available).

    See that in the example below there’s no "Script error" and every "Error Object" have a stack.

    <script>
      window.addEventListener("error", function(e) {
        console.error("window error handler:", e);
      })
    </script>
    
    <!-- CHANGE: The `defer` attribute is added to this script. -->
    <script src="https://github.com/user-attachments/files/17729754/codemirror6-november-13-2024.txt" defer></script>
    
    <script>
      let { EditorView } = CM["@codemirror/view"];
    </script>
    
    <script>
      new EditorView(null); // Example 1: just "Script error."
    </script>
    
    <script type="module">
      new EditorView(null); // Example 2: just "Script error."
    </script>
    
    <script type="module">
      await new Promise(r => setTimeout(r, 10));
      new EditorView(null); // Example 3: just "Script error."
    </script>
    
    <script>
      (async function() {
        new EditorView(null); // Example 4: no window error event at all??
      })();
    </script>
    
    <script type="module">
      let { EditorView } = await import("https://esm.sh/@codemirror/[email protected]");
      new EditorView(null); // Example 5: ✅ produces error event with the actual error attached 
    </script>
    
    
    <!-- note: this uses a data url, but i tested using an actual server to server this file and it's the same result -->
    <script src="data:text/plain,window.foo=function(a){a.b.c}" defer></script>
    <script>
      foo(1); // Example 6: ✅ produces error event with the actual error attached 
      // caveat: in firefox, specifically, this data URL version gives "Script error.", but substituting it with a server url version results in the same behavior as chrome.
      // chrome gives the 'correct' behavior for both cases.
    </script>
    Login or Signup to reply.
  2. The code is logically correct, but parts of it may need to be reviewed or changed to ensure that all errors are corrected. A few points to check more closely:

    Not calling a module or library without a valid value: In code, you EditorView(null); You called without a valid value, which produces an error. This command may give an error if the CodeMirror library is not loaded correctly. Make sure CodeMirror is downloaded from the correct source.

    Library access: It looks like EditorView is in the CodeMirror library, and you used a GitHub link to download it. Note that GitHub does not allow direct upload of JavaScript files by default. For CodeMirror to work properly, make sure you download it from a source, either a CDN or a local installation.

    Lack of await support in normal script: In one of the sections, you have used await without inside the async function. From await, you must enter an async script or async function.

    Compatibility with different browsers: The different behavior you see in browsers can be due to differences in security and each browser. To fix this problem and ensure consistency, handle your errors in different ways.

    In general, if you make a mistake or don’t execute the code correctly, you can check any error seriously and use valid errors to see the actual error message instead of the generic message.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search