我主要来自 Java 背景(因此具有 Java 思维),所以我不确定我在这里是否有任何意义。
我正在尝试找到将错误记录到浏览器的 Web 控制台的正确方法(抛出在堆栈中较高的某个位置,稍后通过较低级别的通用 catch
block 捕获),同时在不错的可折叠方式。以下是示例,来自 Slack chat web client在 Firefox 上运行:
如您所见,默认情况下仅显示错误消息(第一个日志),前面有一个可折叠的箭头图标,单击该图标会展开完整的堆栈跟踪(第二个日志)。非常整洁,我会说。
这是我试过的:
在嵌套函数调用中创建错误:
h = () => TypeError("b");
g = () => h();
f = () => g();
e = f();
生成的错误对象现在存储在 e
中.
e
, 当传递给 console.error()
, 确实显示了折叠的堆栈跟踪,但显然它反射(reflect)了 console.error()
的调用位置本身(跟踪只有一个 <anonymous> debugger eval code
行),除了正确堆栈跟踪的不可折叠副本(包含 f
、 g
和 h
函数):
折叠的(默认) View ,它仍然显示(正确的)堆栈跟踪:
扩展 View ,显示两个堆栈跟踪(现在扩展的“错误”堆栈跟踪位于底部):
或者,如果我做类似的事情:
h = () => {
throw TypeError("b");
}
g = () => h();
f = () => g();
e = f();
我只是得到一个没有堆栈跟踪的单行代码:
(注意:Chrome 在这里的行为似乎有所不同,给出类似于 console.error(e)
的内容;在这种情况下,两个堆栈跟踪都是正确的,但仍然有两个跟踪,一个是不可折叠的。)
如果我执行 console.error()
仅在原地使用消息文本(就在应该产生错误的地方):
h = () => {
console.error("b");
}
g = () => h();
f = () => g();
e = f();
我看到了预期的行为:
然而,显然这不是一个可行的解决方案,因为我需要的是在较低级别(例如,原始驱动程序函数中的主 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/