Joseph Katzman
Joseph Katzman

Reputation: 2083

Catching Exception inside nested Using statement of NHibernate

What is the right way to handle exception inside nested using statement? I have the following part of code:

public void Create(Entity entity)
{
    try
    {
        using (ISession session = NhibernateHelper.OpenSession())
        {
            try
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Save(entity);
                    transaction.Commit();
                }
            }
            catch (TransactionException transactionException)
            {
                // log it
                throw;
            }
        }
    }
    catch (TransactionException transactionException)
    {
        // log it
        throw;
    }
    catch (SessionException sessionException)
    {
        // log it
        throw;
    }
    catch (Exception exception)
    {
        // log it
        throw;
    }
}

I saw few answers when people put try/catch statement inside nested using. I know that using statement consists of try/finally. And my question is about right way to catch all possible exceptions. Should I do rollback inside one of catch statements? Could you provide me the right way to do it?

Upvotes: 1

Views: 883

Answers (2)

Frédéric
Frédéric

Reputation: 9864

I tend to minimize "try catch" clauses as much as possible.

Nesting "try catch" and logging each catch (while not swallowing exception) may cause a same exception to be logged multiple times, which bloats the logs. And having "try catch" everywhere bloats the code.

I do not see the need for explicitly rollbacking a failed transaction : non committed transaction are rollbacked on dispose by default.

My usual pattern with MVC/webform is to use a global action filter (usually derived from HandleErrorAttribute) for logging exception, and/or a dedicated IHttpModule. So no need for "try catches" anywhere else just for logging while not swallowing the exception.

(With MVC, I usually explicitly rollback failed transaction because I am using an action filter for opening them OnActionExecuting, committing or rollbacking them OnActionExecuted depending on filterContext state. There, especially if there was an error, I may add a swallowing and logged try catch around the rollback: it may fails too, and I consider this failure should not mask the one having caused the app to try rollbacking.)

Upvotes: 3

Andrew Shepherd
Andrew Shepherd

Reputation: 45262

I follow the pattern of always beginning a try..catch block immediately after BeginTransaction().

Other than that, I think it's fine to not add any other exception checking - just let it propagate out to the calling code.

 using (var session = NhibernateHelper.OpenSession())
 {
      using(var transaction = session.BeginTransaction())
      {
           try
           {
               //
               // Add a block of code here which queries and
               // modifies data
               //
               //
               transaction.Commit();
           }
           catch(Exception ex)
           {
                transaction.RollBack();
                throw;
           }
      }
 }

Upvotes: 0

Related Questions