【问题标题】:Javascript - can you throw an object in an Error?Javascript - 你可以在错误中抛出一个对象吗?
【发布时间】:2018-11-29 23:02:32
【问题描述】:

是否可以使用Error 抛出一个对象?在下面的示例中,控制台显示undefined

try {
    throw Error({foo: 'bar'});
} catch (err) {
    console.log(err.message.foo);
}

【问题讨论】:

  • 你可以抛出任何东西,但这不是你调用错误构造函数的方式......
  • @dandavis throw new Error()throw Error() 没有区别。
  • @K48:我是指将不可字符串化的对象传递给构造函数...

标签: javascript error-handling


【解决方案1】:

您可以抛出自己的对象,并将错误实例与之关联:

try {
  // ...
  throw {
    foo: "bar",
    error: new Error()
  };

throw 语句不挑剔,但Error() 构造函数挑剔。当然,如果你抛出的东西不是错误,那么它只有在捕获环境期望它是你抛出的任何东西时才有用。

将 Error 对象作为自定义抛出值的一部分很有用,因为构造的 Error 实例具有(在支持浏览器中,目前似乎基本上是所有浏览器)关联的堆栈跟踪。

【讨论】:

    【解决方案2】:

    您可以尝试将对象转换为 JSON 字符串,然后在 catch 语句中将错误消息解析为 JSON 对象:

    try {
        throw Error(JSON.stringify({foo: 'bar'}));
    } catch (err) {
        console.log(JSON.parse(err.message).foo);
    }
    

    【讨论】:

    • JSON.stringify() 在这种情况下将返回 []
    【解决方案3】:

    对于使用 的任何人,您可以扩展ErrorConstructor 接口并添加自己的构造函数来接受这样的对象:

    class MyError extends Error {
      readonly id: number
    
      // base constructor only accepts string message as an argument
      // we extend it here to accept an object, allowing us to pass other data
      constructor({ id, name, message }) {
        super(message)
        this.name = name // this property is defined in parent
        this.id = id
      }
    }
    

    用法

    function doSomething() {
      if (somethingWentWrong) {
        throw new MyError({
          id: 502,
          name: "throttle_violation",
          message: "Violation of backoff parameter",
        });
      }
    }
    
    try {
      doSomething()
    } catch (err) {
      if (err instanceof MyError) {
        console.log("error id: " + err.id);
        console.log("error name: " + err.name);
        console.log("error message: " + err.message);
        alert(err.property); // name
      } else {
        // ...
      }
    }
    

    【讨论】:

      【解决方案4】:

      使用JSON.stringify()JSON.parse() 可能会很痛苦,甚至没有必要。我建议为 Error 对象创建自己的属性,而不是将对象传递给仅接受字符串的 message 参数。

      try {
        let error = new Error();
          
        Object.assign(error, { foo: 'bar' });
      
        throw error;
      } catch (err) {
        console.log(err.foo);
      }
      

      【讨论】:

      • 这对于所有情况都是一个不错的选择,除非您想使用 instanceOf 根据抛出的错误类型更改捕获行为
      • @SandyGifford 在这种情况下,只需使用 Object.assign 而不是扩展运算符,即 Object.assign(error, { foo: 'bar' })
      猜你喜欢
      • 2022-11-27
      • 1970-01-01
      • 1970-01-01
      • 2020-08-07
      • 2014-02-09
      • 1970-01-01
      • 2013-02-23
      • 2023-03-25
      • 2012-03-11
      相关资源
      最近更新 更多