javascript - 使用可折叠的堆栈跟踪将 JavaScript 错误正确记录到控制台

标签 javascript exception cross-browser console.log error-logging

我主要来自 Java 背景(因此具有 Java 思维),所以我不确定我在这里是否有任何意义。

我正在尝试找到将错误记录到浏览器的 Web 控制台的正确方法(抛出在堆栈中较高的某个位置,稍后通过较低级别的通用 catch block 捕获),同时在不错的可折叠方式。以下是示例,来自 Slack chat web client在 Firefox 上运行:

Slack's error messages, with nice, collapsible stacktraces!

如您所见,默认情况下仅显示错误消息(第一个日志),前面有一个可折叠的箭头图标,单击该图标会展开完整的堆栈跟踪(第二个日志)。非常整洁,我会说。

这是我试过的:

在嵌套函数调用中创建错误:

h = () => TypeError("b");
g = () => h();
f = () => g();
e = f();

生成的错误对象现在存储在 e 中.

e , 当传递给 console.error() , 确实显示了折叠的堆栈跟踪,但显然它反射(reflect)了 console.error() 的调用位置本身(跟踪只有一个 <anonymous> debugger eval code 行),除了正确堆栈跟踪的不可折叠副本(包含 fgh 函数):

折叠的(默认) View ,它仍然显示(正确的)堆栈跟踪:

'console.error(e)' collapsed; see the ugly stacktrace that doesn't collapse?

扩展 View ,显示两个堆栈跟踪(现在扩展的“错误”堆栈跟踪位于底部):

same thing, with the 'collapse' expanded; now we see two stacktraces (including the 'fake' one that had been collapsed earlier)

或者,如果我做类似的事情:

h = () => {
    throw TypeError("b");
}
g = () => h();
f = () => g();
e = f();

我只是得到一个没有堆栈跟踪的单行代码:

uncaught throw, no stacktrace in Firefox

(注意:Chrome 在这里的行为似乎有所不同,给出类似于 console.error(e) 的内容;在这种情况下,两个堆栈跟踪都是正确的,但仍然有两个跟踪,一个是不可折叠的。)

如果我执行 console.error()仅在原地使用消息文本(就在应该产生错误的地方):

h = () => {
    console.error("b");
}
g = () => h();
f = () => g();
e = f();

我看到了预期的行为:

'console.error()' in-place, with the collapsible stacktrace expanded; just like Slack

然而,显然这不是一个可行的解决方案,因为我需要的是在较低级别(例如,原始驱动程序函数中的主 catch block )记录任意错误(在堆栈中较高位置生成) .

h = () => {
    throw TypeError("b");
}
g = () => h();
f = () => g();

try {
    e = f();
} catch (e) {
    // expecting to see an error log, with one nice, collapsible stacktrace
    console.error(e);
}

我的一位同事建议,执行此操作的正确方法可能是覆盖默认值 console.error()与我自己的自定义实现一起运行,这就是 Slack 也可能发挥魔力的方式。这是唯一的解决方法,还是有更“标准化”(和跨浏览器)的解决方案,我可以开箱即用(最好不依赖外部库)?

最佳答案

(注意:Chrome 和 Firefox 对此的处理方式不同)。

您在顶层捕获错误并在那里进行处理。在 Firefox 中,您会看到堆栈,但它不会折叠。

从概念上讲,它是这样工作的。想象克拉是误差的移动。

^    excution > 
^     function > 
^      function > 
^       function > error thrown (no handling) // shows stack.

^    excution  (handling) > 
     function > 
      function > 
       function > error thrown // does not show stack (in Chrome), because you're handling up here, 

^    excution > 
^     function > 
^      function > 
^       function > error thrown, caught. Catch uses console.error // shows stack because the error is at a different layer in the stack

现在查看您的示例的编辑版本,其中处理较低。

h = () => {
     try {
        throw TypeError("b");
    } catch (e) {
         // expecting to see an error log, with one nice, collapsible stacktrace
         console.error(e);
    }
}
g = () => h();
f = () => g();

f();

此代码显示堆栈。

您在希望处理的级别“捕获”错误。将其深入调用的目的是,您可以处理影响调用函数的代码的错误,这些代码以您希望的方式抛出。

关于javascript - 使用可折叠的堆栈跟踪将 JavaScript 错误正确记录到控制台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50283846/

相关文章:

javascript - 一个可靠的 Javascript 计时器

c++ - 将 std::runtime_error 捕获为 std::exception 时出错

javascript - 什么是 JavaScript 的跨浏览器支持 1. 7's new features? Specifically array comprehensions and the "let"声明

javascript - Javascript跨浏览器窗口onload方法

spring - 如何在IntelliJ IDEA中应用@ControllerAdvice?

javascript - 如何在文本框点击事件中设置文本框中字符的第一个位置 ---Chrome Issue

javascript - 在 <select> 框中选择选项的最正确方法

javascript - 如何在 React JS 中获取最后访问的路线/状态?

javascript - 用于 Google 的 Jquery 脚本,如鼠标悬停时的 POP Up 图像

java - 有时抛出 java.util.ConcurrentModificationException