在使用异步/等待捕获的错误时如何避免嵌套错误消息?

时间:2019-01-17 16:45:14

标签: javascript error-handling async-await

我已经看到了以下三种抛出错误的变体。

var response = await api.call()
    .catch((error) => {
        throw error;
    });

var response = await api.call()
    .catch((error) => {
        throw Error(error);
    });

var response = await api.call()
    .catch((error) => {
        throw new Error(error);
    });

我尝试过throw new Error(error),但是传递错误的一系列异步函数导致:

  

“错误:错误:错误:实际错误消息”

推荐其中哪些?

2 个答案:

答案 0 :(得分:1)

 throw Error(error);

之所以起作用,是因为JS始终将本机构造函数作为构造函数执行,即使您将它们作为函数调用也是如此。就像分号插入一样,虽然可以使用,但我不建议您依赖它,因为它会造成混淆,并且可能会带来不良的副作用。基本上,如果一切都按预期进行,则与以下相同:

 throw new Error(error);

现在,这也毫无意义,因为您丢失了error的堆栈跟踪。当构造错误对象时,将收集有关错误如何发生的大量信息,这对于调试非常有用。由于错误构造函数期望将字符串作为第一个参数,因此error被强制转换为字符串,基本上是:

 throw new Error(error.toString());

并通过字符串化,仅保留消息而丢失其他所有内容。您会得到一个错误,该错误发生在上面的行中,该行隐藏了它的起源位置,而:

 throw error;

只是将错误向上传递,它将保留所有必填信息。


为清楚起见,我个人不希望将ableable和async / await混合使用,所以我会这样做:

try {
  const response = await api.call()
} catch(error) {
    // Some logging, handling, etc.
    throw error;
}

如果您无法正确处理错误并始终重新抛出错误,则这是毫无意义的,只是不要trycatch。在调用堆栈中的某个地方处理它,在那里您可以实际处理它。

答案 1 :(得分:0)

均不推荐使用。如果您无法处理错误,请不要抓住它。但是,如果捕获到 some 错误,则应按原样抛出 错误,以保留所有调试信息:

somePromise()
  .catch(reason => {
    if (/* some test about the error */) {
      // handles some errors
    } else {
      throw reason; // <- more on that on @JonasWilms' answer
    }
  })