异常处理中的异常处理

Exception Handling within Exception Handling

异常处理异常处理中的最佳实践是什么?

我发现自己在一个现有的 C#(Framework 4.0)系统上工作,该系统在 catch 中使用自定义对象,并最终阻塞整个系统的大部分应用服务器层。

考虑此代码库中方法的以下片段版本:

    public void DoSomeStuff(string sGUID)
    {
        try
        {
            // Foo
        }
        catch (Exception oEx)
        {
            oExceptions.Add(oEx);

            if (oDBConn.NumberOfActiveTrans > 0)
            {
                oDBConn.Rollback();
            }
        }
        finally
        {
            oDBConn.DeleteLocksByGUID(sGUID);
        }
    }

我可能过于偏执了,但我发现自己非常担心这些可能发生的未处理异常。

因此,像以下更新版本这样的做法是否可以接受,或者是否有更好的方法来完成同样的事情?

    public void DoSomeStuff(string sGUID)
    {
        try
        {
            // Foo
        }
        catch (Exception oEx)
        {
            oExceptions.Add(oEx);

            try
            {
                if (oDBConn.NumberOfActiveTrans > 0)
                {
                    oDBConn.Rollback();
                }
            }
            catch (Exception oEEx)
            {
                oExceptions.Add(oEEx);
            }
        }
        finally
        {
            try
            {
                oDBConn.DeleteLocksByGUID(sGUID);
            }
            catch (Exception oFEx)
            {
                oExceptions.Add(oFEx);
            }
        }
    }

我个人是不会在finally里面加一个try catch块的,那它就可以是一个无穷无尽的链条了。通常你不应该在 finally 中有复杂的东西,并且在任何情况下都应该在调用者中捕获意外异常。

编辑:仔细观察代码,我不明白为什么 finally 中的代码不应该在 try 块中。

I might be being overly paranoid, but I find myself very worried about possible unhandled exceptions that may occur with these.

不要惊慌。如果 db 层中有错误,请尝试在那里捕获它。

原始代码中最危险的是,如果它失败并且事务回滚失败,唯一重新抛出的错误将是回滚事务的错误。您永远不会知道导致您不得不回滚事务的原始异常是什么。这可能是您最关心的。

想偏执就把事务回滚失败记录下来。但重要的是之前的异常让你走到了那一步。应该根据调用者的期望记录或重新抛出。