node.js - 在(嵌套)try/catch/finally 块中处理 nodejs 中的错误
问题描述
我正在重构我的 nodejs 代码。我正在使用 node-postgres 实现事务。我的代码现在看起来像这样:
const controller = async (req, res, next) => {
const client = await pool.connect()
try {
// get the user ID out of the params in the URL
const { user_id } = req.params
let query, values, result
try {
await client.query('BEGIN')
} catch (err) {
throw new CustomError(err)
}
try {
query = 'QUERY_1'
values = ['VALUES_1']
result = await client.query(query, values)
} catch (err) {
throw new CustomError(err)
}
// handle some stuff
try {
query = 'QUERY_2'
values = ['VALUES_2']
result = await client.query(query, values)
} catch (err) {
throw new CustomError(err)
}
// handle some more stuff
try {
await client.query('COMMIT')
} catch (err) {
throw new CustomError(err)
}
return res.status(200).json({ response: 'ok' })
} catch (err) {
await client.query('ROLLBACK')
return next(new CustomHandleError(400, 'something_went_wrong'))
} finally {
client.release()
}
}
这段代码有效,但我有一些问题。我是 nodejs 的初学者。
1)在我的'finally'块中,我将客户端释放回池中。但是当一切正常时,我会在“尝试”块中返回响应。在线我读到'finally'块总是被执行,那么在try块中返回一个(好的)响应并在finally块中释放客户端是否可以?
2)嵌套多个try catch块是否可以(或者是反模式)。原因是 node-postgres 抛出错误,但我想将所有错误返回给自定义错误处理程序,所以我首先捕获这些错误,然后在我的 CustomError 处理程序中再次抛出它们。
提前致谢!
解决方案
您可以大大简化您的 try/catch 处理,因为所有内部catch
块都做同样的事情并且不是必需的:
const controller = async (req, res, next) => {
const client = await pool.connect()
try {
// get the user ID out of the params in the URL
const { user_id } = req.params
let query, values, result;
await client.query('BEGIN');
query = 'QUERY_1'
values = ['VALUES_1']
result = await client.query(query, values)
// handle some stuff
query = 'QUERY_2'
values = ['VALUES_2']
result = await client.query(query, values)
// handle some more stuff
await client.query('COMMIT')
return res.status(200).json({ response: 'ok' })
} catch (err) {
await client.query('ROLLBACK')
return next(new CustomHandleError(400, 'something_went_wrong'))
} finally {
client.release()
}
}
然后,针对您的问题:
1)在我的'finally'块中,我将客户端释放回池中。但是当一切正常时,我会在“尝试”块中返回响应。在线我读到'finally'块总是被执行,那么在try块中返回一个(好的)响应并在finally块中释放客户端是否可以?
是的,这是一个很好的使用finally
.
2)嵌套多个try catch块是否可以(或者是反模式)。原因是 node-postgres 抛出错误,但我想将所有错误返回给自定义错误处理程序,所以我首先捕获这些错误,然后在我的 CustomError 处理程序中再次抛出它们。
没关系(当它达到特定目标时不是反模式),但在这种情况下没有必要,因为你所有的内部catch()
块都做同样的事情并且都被你的外部 catch 块捕获,所以你可以保持外部捕获并摆脱所有内部捕获。如果您的所有语句在我的代码中拒绝,那么您的所有await
语句都将直接转到您的外部catch
,而您在上面的所有内部 catch 语句都在做所有事情,因此它们是多余的。
需要内部捕获的一些原因是:
您想要创建一个自定义错误(对于每个异步操作都不同),您将在函数的最终结果中实际使用该错误。
您想在本地“处理”错误并继续处理不同的代码路径,而不仅仅是立即返回错误。例如,您尝试加载配置文件,捕获错误,如果配置文件不存在,则使用默认值继续执行函数中的其余代码。