使用自定义错误处理程序中止多步承诺链
Aborting multiple-step promise chains with custom error handlers
我正在编写一个多步异步序列,每一步都涉及不同的可能错误。如果发生错误,我想中止整个序列。
我正在尝试使用 Promise.then()
和 Promise.catch()
将其表示为线性序列。这是伪代码:
step1()
.catch(errorAtStep1 => handlerErrorAtStep1)
.then(resultOfStep1 => step2(resultOfStep1))
.catch(errorAtStep2 => handlerErrorAtStep2)
.then(resultOfStep2 => step3(resultOfStep2))
...
我知道我需要在每个错误处理程序中抛出 东西 以避免返回到 then(result)
部分。但是,当我抛出时,执行在下一个 catch(error)
块中结束,该块预期会出现与其相应步骤相关的错误,而不是我抛出的其他内容。
我的问题是:有什么简洁的方法可以处理此问题,从而最大限度地减少阅读代码时的注意力分散?
我想出了这个 class:
class AbortChainError extends Error {
static chain(handler) {
return function(error) {
if (error instanceof AbortChainError) throw error
handler(error)
throw new AbortChainError()
}
}
}
允许 catch()
块被写为:
.catch(AbortChainError.chain(errorAtStep2 => handlerErrorAtStep2))
额外需要在序列末尾写入一个最终的空 catch()
块。
我们可以做得更好吗?
如果你把它放到一个异步函数中,我没有错误处理程序 return 什么,然后你可以执行每个步骤 one-by-one 并查看结果是否存在 - 如果没有,出现错误,你可以 return.
const doStuff = async () => {
const r1 = await step1().catch(handlerErrorAtStep1);
if (!r1) return;
const r2 = await step2(r1).catch(handlerErrorAtStep2);
if (!r2) return;
// etc
它不是最 DRY,但我认为它是最容易理解的。
我正在编写一个多步异步序列,每一步都涉及不同的可能错误。如果发生错误,我想中止整个序列。
我正在尝试使用 Promise.then()
和 Promise.catch()
将其表示为线性序列。这是伪代码:
step1()
.catch(errorAtStep1 => handlerErrorAtStep1)
.then(resultOfStep1 => step2(resultOfStep1))
.catch(errorAtStep2 => handlerErrorAtStep2)
.then(resultOfStep2 => step3(resultOfStep2))
...
我知道我需要在每个错误处理程序中抛出 东西 以避免返回到 then(result)
部分。但是,当我抛出时,执行在下一个 catch(error)
块中结束,该块预期会出现与其相应步骤相关的错误,而不是我抛出的其他内容。
我的问题是:有什么简洁的方法可以处理此问题,从而最大限度地减少阅读代码时的注意力分散?
我想出了这个 class:
class AbortChainError extends Error {
static chain(handler) {
return function(error) {
if (error instanceof AbortChainError) throw error
handler(error)
throw new AbortChainError()
}
}
}
允许 catch()
块被写为:
.catch(AbortChainError.chain(errorAtStep2 => handlerErrorAtStep2))
额外需要在序列末尾写入一个最终的空 catch()
块。
我们可以做得更好吗?
如果你把它放到一个异步函数中,我没有错误处理程序 return 什么,然后你可以执行每个步骤 one-by-one 并查看结果是否存在 - 如果没有,出现错误,你可以 return.
const doStuff = async () => {
const r1 = await step1().catch(handlerErrorAtStep1);
if (!r1) return;
const r2 = await step2(r1).catch(handlerErrorAtStep2);
if (!r2) return;
// etc
它不是最 DRY,但我认为它是最容易理解的。