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



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

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),但一系列异步函数传递错误导致:

"错误:错误:实际错误消息">

建议使用以下哪一项?

throw Error(error);

这只是因为JS总是将本机构造函数作为构造函数执行,即使您将它们作为函数调用也是如此。这就像分号插入一样,虽然它有效,但我不建议依赖它,因为它令人困惑,可能会带来不必要的副作用。基本上,如果一切都按预期工作,它与相同

throw new Error(error);

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

throw new Error(error.toString());

通过字符串化,你只会保留信息,而失去其他一切。你会得到一个发生在上面一行的错误,它隐藏了它的来源,而:

throw error;

只是传递错误,这将保留所有强制信息。


为了清晰起见,我个人不喜欢混合使用二进制和异步/等待,所以我会这样做:

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

如果你不能正确处理错误,并且总是重新抛出,这是没有意义的,只是不要trycatch。在调用堆栈的某个地方处理它,在那里你可以实际处理它。

不推荐使用任何一种。如果你不能处理错误,就不要捕捉它。但是,如果你捕捉到一些错误,你应该按原样抛出错误,以保留所有调试信息:

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

相关内容

最新更新