如何解决内部函数或调用函数是否应该包装在try-catch块中以进行正确的错误处理?
内部函数或调用函数是否应该包装在try-catch块中以进行正确的错误处理?
示例1
// Async function definition
const getLatestRecords = async() => {
try {
const records = await Record.find({})
return records
} catch(e) {
console.error(e)
}
}
// Async function call without error handling - will this suffice?
let records
const callAsyncFunction = async() => {
records = await getLatestRecords()
}
callAsyncFunction()
// Same async function call with error handling - or should it be like this?
let records
const callAsyncFunctionWithTryCatch = async() => {
try {
records = await getLatestRecords()
} catch(e) {
console.error(e)
}
}
callAsyncFunctionWithTryCatch()
Q1)在上面的示例中,异步函数定义 getLatestRecords()已经包装在try-catch块中,用于错误处理。尽管如此,由 callAsyncFunction()定义的调用函数是否足够,还是应该将异步函数调用也包装在try-catch块中,如 callAsyncFunctionWithTryCatch()所示? >?
示例2
// Test without try catch block - will this suffice?
test('Should delete records with valid id',async() => {
const record = await new Record().save()
const res = await request(app)
.delete(`/records/${record._id}`)
.expect(200)
expect(await Records.countDocuments()).toBe(0)
})
// Test with try catch block - should all tests with await in them be wrapped in a try catch block?
test('Should delete records with valid id',async() => {
try {
const record = await new Record().save()
const res = await request(app)
.delete(`/records/${record._id}`)
.expect(200)
expect(await Records.countDocuments()).toBe(0)
} catch(e) {
console.error(e)
}
})
问题2)类似地,对于测试,是否应将所有包含等待调用的测试包装在try catch块中?请记住,如果发生问题,您希望测试失败,所以我对此不太确定。
解决方法
仅当知道可以处理该函数中的错误 的所有内容时,才应将它们括在try/catch
中。否则,应让函数的消费者决定如何处理错误。例如,对于getLatestRecords
,如果脚本使用的地方周围有各种不同的点,则根据上下文的不同,让这些不同的点处理错误可能是最有意义的。例如:
const getLatestRecords = async () => {
const records = await Record.find({})
return records
}
// could also just do: `return Record.find({})`
getLatestRecords()
.then(doStuff)
.catch((err) => {
res.status(500).send('Could not retrieve records for ' + user);
});
另一方面,如果将try
/ catch
放在内部getLatestRecords
函数中,则使用者必须通过检查返回值是否存在来检查是否发生了错误,而不是.catch
,这有点奇怪。
如果所有await
都在try/catch
内部,则包含async
的函数将永远不会拒绝。因此,将那个async
函数的调用者放进try/catch
里面不会做任何事情,因为内部函数永远不会拒绝; catch
将永远不会输入。也就是说,对于此示例:
const getLatestRecords = async() => {
try {
const records = await Record.find({})
return records
} catch(e) {
console.error(e)
}
}
const callAsyncFunctionWithTryCatch = async() => {
try {
records = await getLatestRecords()
} catch(e) {
console.error(e)
}
}
callAsyncFunctionWithTryCatch()
是多余的;简化为
const getLatestRecords = async() => {
try {
const records = await Record.find({})
return records
} catch(e) {
console.error(e)
}
}
const callAsyncFunctionWithTryCatch = async() => {
records = await getLatestRecords()
}
callAsyncFunctionWithTryCatch()
(或仅捕获callAsyncFunctionWithTryCatch
-但不捕获两者)
- 异步功能调用也应该包装在try-catch块中
如果将async
函数包装在try / catch中,则除非有一些可能引发错误并且没有被try / catch包装的代码,否则您无需在多个级别上使用它。例如:
const getLatestRecords = async() => {
aFunctionWhichCanThrow(); // <= Only need try/catch in caller fn for this
try {
const records = await Record.find({})
return records
} catch(e) {
console.error(e)
}
}
即使在那种情况下,您可能也想通过全局unhandledRejection
处理程序来处理错误。
- 所有带有等待调用的测试都应该包装在try catch块中
是的,可以抛出/拒绝的测试应该包装在try / catch块中。情况可能像这样:
- 功能应该不抛出
- 尝试-验证功能响应
- 捕获-测试失败
- 应该抛出函数
- 尝试-测试失败
- 捕获-验证错误
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。