在(嵌套的)try/catch/finally 块中处理 nodejs 中的错误 [英] Handling errors in nodejs in (nested) try/catch/finally blocks

查看:89
本文介绍了在(嵌套的)try/catch/finally 块中处理 nodejs 中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在重构我的 nodejs 代码.我正在使用 node-postgres 实现事务.我的代码现在看起来像这样:

I'm refactoring my nodejs code. I'm implementing transactions using node-postgres. My code now looks like this:

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 的初学者.

This code works, but I have some questions. I'm a beginner at nodejs.

1) 在我的finally"块中,我将客户端释放回池中.但是当一切正常时,我会在尝试"块中返回响应.我在网上读到finally"块总是被执行,那么在 try 块中返回一个(好的)响应并在 finally 块中释放客户端是否可以?

1) In my 'finally' block, I release the client back to the pool. But when everything is OK, I return the response in the 'try' block. Online I read that the 'finally' block is ALWAYS executed, so is it OK to return a (good) response in the try block and releasing the client in the finally block?

2) 嵌套多个 try catch 块是否可以(或者是反模式).原因是 node-postgres 抛出错误,但我想将所有错误返回给自定义错误处理程序,所以我首先捕获这些错误,然后在我的 CustomError 处理程序中再次抛出它们.

2) Is it OK (or is it anti-pattern) to nest multiple try catch blocks. The reason is that the node-postgres throws errors but I want to return all errors to a custom error handler, so I catch those errors first and then throw them again in my CustomError handler.

提前致谢!

推荐答案

您可以显着简化您的 try/catch 处理,因为所有内部 catch 块都执行相同的操作并且不是必需的:

You can significant simplify your try/catch handling since all the inner catch blocks all do the same thing and are not necessary:

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 块中?

1) In my 'finally' block, I release the client back to the pool. But when everything is OK, I return the response in the 'try' block. Online I read that the 'finally' block is ALWAYS executed, so is it OK to return a (good) response in the try block and releasing the client in the finally block?

是的,这是 finally 的一个很好的用法.

Yes, this is a good use of finally.

2) 嵌套多个 try catch 块是否可以(或者是反模式).原因是 node-postgres 抛出错误,但我想将所有错误返回给自定义错误处理程序,所以我首先捕获这些错误,然后在我的 CustomError 处理程序中再次抛出它们.

2) Is it OK (or is it anti-pattern) to nest multiple try catch blocks. The reason is that the node-postgres throws errors but I want to return all errors to a custom error handler, so I catch those errors first and then throw them again in my CustomError handler.

没关系(当它实现特定目标时不是反模式),但在这种情况下没有必要,因为所有内部 catch() 块都做同样的事情并且都是刚被你的外挡块抓住,这样你就可以保留外挡块并摆脱所有内部的挡块.你所有的 await 语句将直接进入你的外部 catch 如果它们在我上面的代码中拒绝,你在所有内部 catch 语句中所做的一切都是多余的,所以它们是多余的.

It's OK (not an anti-pattern when it achieves a specific goal), but in this case it is not necessary because all your inner catch() blocks all do the same thing and are all just caught by your outer catch block so you can just keep the outer catch and get rid of all the inner ones. All your await statements will just go directly to your outer catch if they reject in my code above which all you were doing anyway with all your inner catch statements so they were redundant.

需要内部捕获的一些原因是:

Some reasons for needing the inner catch are:

  1. 您想要创建一个自定义错误(每个异步操作都不同),您将在函数的最终结果中实际使用该错误.

  1. You want to create a custom error (that is different for each async operation) that you will actually use in the final result of the function.

您想在本地处理"错误并继续沿不同的代码路径处理,而不仅仅是立即返回错误.例如,您尝试加载配置文件,捕获错误,然后在配置文件不存在的情况下使用默认值继续执行函数中的其余代码.

You want to "handle" an error locally and continue processing down a different code path that is not just an immediate error return. For example, you attempt to load a config file, catch the error and just proceed with the rest of the code in your function with defaults if the config file is not present.

这篇关于在(嵌套的)try/catch/finally 块中处理 nodejs 中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆