【发布时间】:2021-09-22 02:52:06
【问题描述】:
我正在开发一个需要向两个 API 发出请求的应用程序。我使用 cognito 来处理身份验证,然后使用 lambda 与数据库通信。但是,我不认为我的问题特定于这些实现中的任何一个。任何两个 api 都可能出现这种情况。
我正在尝试编写注册新用户的过程。我需要在 cognito 中创建一个新用户,以便新用户能够登录,然后我需要在数据库中创建一个相应的用户,该用户将为该用户存储非身份验证相关数据。如果其中一个 api 请求遇到错误,那么我需要删除我在另一个 api 中创建的项目。
我目前的实现基本上是这样的:
const signUpNewUser = (userInfo) => {
API.post("user", "/user", userInfo)
.then((response) => {
return COGNITO.post("user", "/user", response.newUserID);
})
.then((res) => {
//BOTH REQUESTS OCCURED WITH NO ERRORS
})
.catch((error) => {
if (error.origin === "COGNITO_ERROR") {
//IF DB CHANGES CONFIRMED BUT COGNITO FAILED, DELETE CREATED GUEST IN DB
return API.delete("guest", "/guest", userInfo);
} else if (error.origin === "DATABASE_ERROR") {
//IF DB CHANGES FAILED THEN COGNITO HAS NOT RUN YET, SO DON'T NEED TO DELETE IN THIS CASE
}
});
};
这遵循了我在互联网上看到的模式。但是,我无法区分认知错误和数据库错误。在上面的代码中,我按 error.origin 对它们进行了排序,但它们实际上并没有可靠地指示其来源的属性。在处理多个不受您控制的 api 时,这个问题一定很常见,但我找不到好的解决方案。
感觉我需要在这种情况下嵌套承诺。我可以在 API.Post 和 COGNITO.post 之后嵌套一个 catch,并使用该 catch 抛出一个具有 origin 属性的新错误。然后它会冒泡并被处理所有错误的最终捕获捕获。像这样:
const signUpNewUser2 = (userInfo) => {
API.post("user", "/user", userInfo)
.catch((err) => {
let parsedError = err;
parsedError.origin = "DATABASE_ERROR";
throw parsedError;
})
.then((response) => {
let newGuestID = response.id;
return COGNITO.post("user", "/user", newGuestID)
.then((res) => {
return res;
})
.catch((err) => {
let parsedError = err;
parsedError.origin = "COGNITO_ERROR";
throw parsedError;
});
})
.then((res) => {
//BOTH REQUESTS OCCURED WITH NO ERRORS
})
.catch((error) => {
if (error.origin === "COGNITO_ERROR") {
//IF DB CHANGES CONFIRMED BUT COGNITO FAILED, DELETE CREATED GUEST IN DB
return API.delete("guest", "/guest", guestInfo);
} else if (error.origin === "DATABASE_ERROR") {
//IF DB CHANGES FAILED THEN COGNITO HAS NOT RUN YET, SO DON'T NEED TO DELETE IN THIS CASE
}
});
};
但是我读到的所有内容都说你应该避免嵌套承诺。
或者,我可以将 API.post 和 COGNITO.post 放在带有内部 .then .catch 语句的单独函数中,然后让这些函数返回一个承诺或抛出一个带有附加属性的错误以指示来源。但是我看到有人说这只是隐藏了问题并使代码更难理解。
我看到的标准模式是,您在 .then 链的末尾有一个捕获,它知道如何处理多种错误。但是,如果您不控制正在使用的 API,您如何自信地对这些错误进行排序?我缺少关于 js 中错误性质的一些基本知识吗?
【问题讨论】:
标签: javascript rest promise try-catch