通过编程捕获Chrome异步Javascript堆栈跟踪

20

我一直在努力为一个只在Chrome上运行的Web应用程序增加更好的错误日志记录。实质上,我想能够捕获并存储堆栈跟踪信息。对于同步代码,这很有效,但对于异步代码,我遇到了一些奇怪的问题。基本上,Chrome似乎会作为其异步堆栈跟踪功能的一部分记录其他信息,但我无法找出如何捕获它。

在Chrome浏览器控制台中运行的代码:

let e;
let a = () => Promise.resolve(null)
.then(() => (null).foo)
.catch(err => {
  console.info(err); 
  console.error(err); 
  e = err;
})
let b = () => a();
let c = () => b();
c();

输出:

(info)
TypeError: Cannot read property 'foo' of null
    at <anonymous>:3:20

(error, after expanding)
TypeError: Cannot read property 'foo' of null
    at <anonymous>:3:20
(anonymous) @ VM1963:6
Promise.catch (async)
a @ VM1963:4
b @ VM1963:9
c @ VM1963:10
(anonymous) @ VM1963:11

所以console.error会给我一个穿过整个调用堆栈的堆栈跟踪,可能是通过某种 Chrome 引擎魔法实现的。console.info会给我在err上存储的实际堆栈跟踪。如果在所有这些操作完成后,我尝试读取e的值,则其堆栈是从console.info语句获取的两行,而不是从console.error语句。

我的问题是,是否有任何方法可以捕获和存储Chrome在我调用console.error时生成和使用的异步堆栈跟踪?


我尝试了一下,发现Chrome显示了错误堆栈...这与传递到catch块内的错误对象无关。 - Ajay Reddy
你是否考虑过使用Object.defineProperty来覆盖console方法?或者类似地,使用Proxy来捕获console调用? - nick zoum
1个回答

2
"console.error()" 看起来是为了方便而调用 "console.trace()"。
似乎脚本无法以除字符串外的任何形式获取堆栈跟踪。例如,可以使用 "err.stack" 来获取该字符串。MDN有关于 "Error" 的 "stack属性" 的文档。虽然它不是规范的一部分,但似乎在所有平台上都得到支持。

3
此外,还有 https://ghub.io/stacktrace-parser 包,能够将字符串形式的堆栈转换为经过适当解析的列表,跨平台。问题在于 err.stack 不包括异步部分,而 console.trace 则包括。Node 有 --async-stack-traces 标志可以解决这个问题。因此问题是:是否有任何方法可以在浏览器中获取异步堆栈跟踪,就像我们在开发工具中看到的那样。 - dy_
2
--async-stack-traces 是一个 v8 标志,因此在 Chrome 中也可能可用。您可能还对 StackTrace.JS 感兴趣,但由于它基于 Error.stack,所以可能也无法处理异步堆栈。 - Ouroborus
是的,npm的stacktrace-js也不包括异步部分。 - phil294

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接