【发布时间】:2021-08-14 00:45:11
【问题描述】:
当我需要进行两次连续的 api 调用时,我更喜欢每个函数来处理它们负责的错误。我一直是这样写的:
class Api {
static call(path) {
...
return Promise.reject({ code: 400/422/... })
}
}
async function closeMonkeyCages() {
try {
await Api.call('monkeys/close')
} catch (err) {
if (err.code === 400) { alert('monkeys arent in the cages yet') }
throw err
}
}
async function feedTigers() {
try {
boom() // example ReferenceError
await Api.call('tigers/feed')
} catch (err) {
if (err.code === 422) { alert('you must pet them first') }
throw err
}
}
(async () => {
try {
await closeMonkeyCages()
await feedTigers()
} catch (err) {
// do nothing, closeMonkeyCages + feedTigers should have already shown alerts
}
})()
但是,此代码很危险。它吞噬了其他错误。如果我的 try 块中有 ReferenceError/TypeError/etc,我希望它被记录(即:Sentry)。
我可以想出几种方法来解决这个问题,但它们看起来要么很乱,要么有点错误,要么不灵活。
- async 函数可以返回 api 异常而不抛出,类似于 fetch api:
const resp = await closeMonkeyCages()
if (!resp.ok) return
await feedTigers()
- 在我的主块中处理 api 异常 (
alert()):
try {
await closeMonkeyCages()
await feedTigers()
} catch (err) {
if (err?.code === 400) { // conditions that map to each error. messy. error-prone
alert(getErrorMsg(err)) // hope this function handles all cases
} else {
// must have been another runtime error
throw err
}
}
- 类型检查错误:
try {
await closeMonkeyCages()
await feedTigers()
} catch (err) {
if (err instanceof Error) {
throw err
}
// do nothing, closeMonkeyCages + feedTigers should have already shown alerts
}
您将如何保持代码的清洁和安全,同时将错误限制在调用它们的函数范围内?
【问题讨论】:
标签: javascript error-handling async-await try-catch