Reputation: 2083
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
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
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