(我最初以为这只是一个 Chrome 错误,但我在 Firefox 中测试过,它有类似的奇怪行为,甚至在
event.message
中使用完全相同的“脚本错误。”字符串,所以我想知道这是否是一个与规范相关的问题。)
我对下面代码的直觉当然是每个测试(我故意在构造函数中输入无效值)应该在
ErrorEvent
处理程序中产生相同的 window.addEventListener("error", ...)
(只是具有不同的行号和内容),但正如该代码块的注释中所述,它们会产生不同的行为。
<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>
Example 4
与需要 window.addEventListener("unhandledrejection", ...)
处理程序有关,但我尝试了,但它没有收到任何事件。ErrorEvent
还包括文件名属性,它给出了导致它的脚本(但不包括行号、堆栈等)我正在构建一个开发人员工具,它可以挂钩页面上的错误事件,以帮助开发人员了解错误的原因/来源。我不控制页面上的代码,因此我需要能够获取错误详细信息,而无需重新编写代码。
因此,不幸的是,“您可以避免以 XYZ 形式编写代码/导入”,这对我来说不是一个解决方案。
请注意,您必须在任何其他脚本运行之前附加事件侦听器,推迟其他脚本,以便它们在初始化程序之后运行(而不是并行)。
另请注意,错误事件具有作为原始错误的错误对象(如果可用,则具有适当的堆栈)。
请注意,在下面的示例中没有“脚本错误”,并且每个“错误对象”都有一个堆栈。
<script>
const errorEventHandler = errorEvent =>
{
errorEvent.preventDefault();
const error = errorEvent?.error;
console.log
(
'Error Event:',
{
Message: errorEvent?.message,
Cause: errorEvent?.cause,
File: errorEvent?.fileName,
Line: errorEvent?.lineNumber,
Stack: errorEvent?.stack,
}
);
console.log
(
'Error Object:',
{
Message: error?.message,
Cause: error?.cause,
File: error?.fileName,
Line: error?.lineNumber,
Stack: error?.stack,
}
);
console.log();
};
console.clear();
window.addEventListener("error", errorEventHandler);
</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" defer></script>
<script defer>
let { EditorView } = CM["@codemirror/view"];
</script>
<script defer>
new EditorView(null); // Example 1: just "Script error."
</script>
<script type="module" defer>
new EditorView(null); // Example 2: just "Script error."
</script>
<script type="module" defer>
await new Promise(r => setTimeout(r, 10));
new EditorView(null); // Example 3: just "Script error."
</script>
<script defer>
(async function() {
new EditorView(null); // Example 4: no window error event at all??
})();
</script>
<script type="module" defer>
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 defer>
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>