JavaScript - 你能在 Error 中抛出一个对象吗?

36

使用Error语句来扔出一个物体是否可能?在下面的例子中,控制台会显示undefined

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

2
你可以抛出任何东西,但这不是如何调用 Error 构造函数... - dandavis
@dandavis:throw new Error()throw Error()之间没有区别。 - user6269864
1
@K48: 我是指向构造函数传递一个不可字符串化的对象... - dandavis
5个回答

52
你可以抛出自己的对象,并将一个错误实例与其关联:
try {
  // ...
  throw {
    foo: "bar",
    error: new Error()
  };

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

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


10

如果您正在使用,您可以扩展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 {
    // ...
  }
}

8
你可以尝试将对象转换为JSON字符串,然后在catch语句中将错误消息解析为JSON对象:
try {
    throw Error(JSON.stringify({foo: 'bar'}));
} catch (err) {
    console.log(JSON.parse(err.message).foo);
}

1
在这种情况下,JSON.stringify()将返回[] - Wei Xia

4

你可以尝试使用“cause”属性

目前TS对其的值类型存在不准确的问题,正在官方论坛上讨论解决方法

try {
     throw new Error('Failed in some way', { 
       cause: {foo: 'bar'} 
     });
} catch(e) {
     console.log(e); // Error('Failed in some way')
     console.log(e.cause) // {foo: 'bar'}
}

或者抛出带有自定义属性的错误实例

try {
     const error = new Error('Failed in some way');
     error.foo = 'bar';
     throw error;
   } catch(e) {
     console.log(e); // Error('Failed in some way')
     console.log(e.foo) // 'bar'
}

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);
}

1
这是一个很好的选择,适用于除了你想使用 instanceOf 根据抛出的错误类型改变 catch 行为的情况。 - Sandy Gifford
2
@SandyGifford 在这种情况下,只需使用Object.assign而不是展开运算符,即Object.assign(error, { foo: 'bar' }) - Chris Haines

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