如何提取 JavaScript 本机异常的所有信息?

How can I extract ALL the information of the JavaScript native exception?

嗯,由于JavaScript是在客户端执行的,我无法控制一堆环境变量,在某些时候,我的应用程序可能会抛出异常。

我想要做的是获取此异常并使我的应用正常失败并向最终用户显示尽可能多的信息(我的最终用户是技术人员) .显然,错误处理可以通过一个简单的 try...catch 块来完成。

让我恼火的是:我怎么知道在 catch 块捕获的本机异常中存储了哪些信息?

我假设浏览器的 JS 引擎抛出的本机异常只是来自 Error 类 的对象,如 运行 这段代码:

try {
  a;
} catch (ex) {
  console.log(ex);
  console.log(new ReferenceError("`Custom` error"));
}

我得到相同的结构:

ReferenceError: a is not defined
    at http://stacksnippets.net/js:14:3
ReferenceError: `Custom` error
    at http://stacksnippets.net/js:17:15

嗯,普通对象的 console.log 与此 略有 不同,但假设 ex 变量是一个对象,我可以循环通过它 for...in,对吗?

嗯,没有。

此代码在日志中未显示 任何内容

try {
  a;
} catch (ex) {
  for (prop in ex) {
    console.log(prop, ": ", ex[prop]);
  }
}

所以,我的问题是: 如何获取存储在本机 JavaScript 异常中的所有信息?

是的,我知道我可以通过 ex.nameex.descriptionex.messageex.stack 等直接访问属性,但我想避免那个。有些浏览器可以实现其他浏览器没有的东西,所以当第一个 运行 时我会遗漏一些信息(正如你在 this question 中看到的那样, stack 属性,例如,首先由 Firefox 实现。

而且,如果有人可以解释,我想了解 JavaScript 异常的真正本质是什么(它们是对象吗?为什么它们在控制台中看起来如此不同?)以及为什么不能我用 for...in 块循环遍历它(可能答案非常相关)。

谢谢。

I would like to understand what is the real nature of the JavaScript exceptions (are they objects? why they look so different in the console?)

Javascript 异常是常规 javascript 对象。可以看到对象定义here

and why can't I loop though it with a for...in block (probably the answers are very related).

使用 for (prop in ex) { 迭代错误的属性不起作用,因为属性未标记为 enumerable(这也通过打印 属性 描述符显示在下面的代码片段中)

您可以切换为使用 getOwnPropertyNames 列出所有属性。

下面的代码说明了如何使用它 - 不确定以这种方式使用 getOwnPropertyNames & ex[property] 是否可以,但这是一个可能的解决方案。

function propsToStr(obj) {
  var str = '';
  for (prop in obj) {
    str += prop + "=" + obj[prop] + ",";
  }
  return str;
}

try {
  a;
} catch (ex) {
  console.log(ex);
  var propertyNames = Object.getOwnPropertyNames(ex);
  propertyNames.forEach(function(property) {
    var descriptor = Object.getOwnPropertyDescriptor(ex, property);
    console.log(property + ":" + ex[property] + ":" + propsToStr(descriptor));
  });
}