Javascript 如何区分错误';基于承诺链中阶段的s源
我有两个回调函数,都调用API并返回Javascript 如何区分错误';基于承诺链中阶段的s源,javascript,es6-promise,Javascript,Es6 Promise,我有两个回调函数,都调用API并返回Promise。它们应该按顺序进行。让我们把它们命名为verifyThing和updateThing 因此,如果没有错误处理,它将与 verifyThing() .then((id) => updateThing(id)) 但现在,错误处理出现了。假设我需要在验证失败或更新失败后显示不同的错误消息。同样很明显,如果验证失败,我不需要调用updateThing 到目前为止,我已尝试使用自定义错误: class VerifyError extends E
Promise
。它们应该按顺序进行。让我们把它们命名为verifyThing
和updateThing
因此,如果没有错误处理,它将与
verifyThing()
.then((id) => updateThing(id))
但现在,错误处理出现了。假设我需要在验证失败或更新失败后显示不同的错误消息。同样很明显,如果验证失败,我不需要调用updateThing
到目前为止,我已尝试使用自定义错误:
class VerifyError extends Error {};
verifyThing()
.catch(e => {
message("cannot verify");
throw new VerifyError();
})
.then((id) => updateThing(id))
.catch(e => {
if (e instanceof VerifyError) return;
message("cannot update");
})
不幸的是,我们使用的Babel6.26出现了自定义错误。作为一个脏补丁,我可以抛出magicstring而不是Error子类,但是ESLint规则是有原因的,对吗
最后我得到了工作变量。但我认为它的可读性较差(因为嵌套):
是否有其他方法来处理同一链中的所有逻辑?似乎可以通过对上一个示例重新排序来实现您想要的实际行为:
verifyThing().then(id =>
updateThing(id).catch(e => {
message("cannot update");
})
).catch(e => {
message("cannot verify");
})
外部的catch()
将只捕获来自verifyThing()
的错误,因为内部的catch()
已经处理了来自updateThing(id)
的错误。此外,您总是得到已解决的承诺,而不是拒绝的承诺,这是适当的,因为这两种类型的错误都已经处理过了
为避免出现错误处理不靠近源的情况,请将内部部分移动到辅助函数:
function tryUpdateThing (id) {
return updateThing(id).catch(e => {
message("cannot update");
});
}
verifyThing().then(
tryUpdateThing
).catch(e => {
message("cannot verify");
});
这是否可读,我将由您决定。如果async/await
是一个选项,那么:
async function() {
let id;
try {
id = await verifyThing();
await updateThing(id);
} catch(e) {
message(id === undefined ? "cannot verify" : "cannot update");
throw e;
}
}
这假设当verifyThing()
满足时,它将使用定义的值进行解析。为什么不直接抛出相应子类型(或错误本身)的本机错误,而不是扩展?在上一个示例中,id
可以是未定义的。那真的是你想要的吗?如果验证失败,我不需要调用updateThing
。换句话说,您的上一个示例确实调用了updateThing
,即使verifyThing
失败。哦,是的,您是对的。尝试提供一些我丢失的throw
的最小示例。已修复。您认为适当子类型的错误是什么意思?
?一个典型的做法是将id存储在子类错误上。不是按实例检查,而是按id检查。顺便说一句,这可以避免对您有多少错误进行n次子类化。谢谢您的示例。我的错误,我的上一个代码示例错过了throw
,因此无法按要求工作。实际上,如果可能的话,我希望避免嵌套.then()
/.catch()
,并使错误处理尽可能靠近错误源。你觉得怎么样?@skyboyer错误处理尽可能接近源代码。当你将updateThing(id).catch(e=>{message(“cannot update”);})
移动到一个helper函数时,这一点更为明显。@skyboyer嵌套的catch
看起来很不幸,但我认为这是处理这类事情的最好方法(message
最好不要抛出,对吗?),还感谢您将call+catch
封装到命名的try…
函数中。看起来(几乎)理想。完全有道理。为了扩展更多步骤,我可能会引入额外的变量errorMessageToShowIfFailOnNextStep
,因此在catch()
中,即使没有if/else
,我也会有相关的错误消息。谢谢
async function() {
let id;
try {
id = await verifyThing();
await updateThing(id);
} catch(e) {
message(id === undefined ? "cannot verify" : "cannot update");
throw e;
}
}