10

This question is more of a what is the RIGHT way to do something...

The question...is there a proper nesting order between a using block and a try/catch?

Is it ok to nest the entire using statement inside of a try/catch and maintain the benefits of a using block? (or will an exception cause the closing portion of the using statement to get thrown out the window)

Or should you nest the try/catch inside the using statements and only surround the statements that do database access?

Is...

try {
     using( tsmtcowebEntities db = new tsmtcowebEntities() ) {
          violationList = ( from a in db.DriverTrafficViolationDetails
                            where a.DriverTrafficViolation.DriverApplicationId == DriverAppId
                            orderby a.DateOfOccurance descending
                            select a ).ToList<DriverTrafficViolationDetail>();
          GeneralViolation = ( from a in db.DriverTrafficViolations
                               where a.DriverApplicationId == DriverAppId
                               select a ).FirstOrDefault();
     }
} catch { }

less/more correct than...

using( tsmtcowebEntities db = new tsmtcowebEntities() ) {
     try {
          violationList = ( from a in db.DriverTrafficViolationDetails
                            where a.DriverTrafficViolation.DriverApplicationId == DriverAppId
                            orderby a.DateOfOccurance descending
                            select a ).ToList<DriverTrafficViolationDetail>();
          GeneralViolation = ( from a in db.DriverTrafficViolations
                               where a.DriverApplicationId == DriverAppId
                               select a ).FirstOrDefault();
     } catch { }
}
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
Jared
  • 5,840
  • 5
  • 49
  • 83
  • Do you really need all the details of your application in the provided code? I think a simple made-up example would suffice. – Jonathon Reinhart Mar 08 '12 at 05:09
  • 1
    The empty catch block is an extremely bad programming practice. Don't do it! You'll regret it later. – phoog Mar 08 '12 at 05:34
  • @JonathonReinhart It was simpler for me to copy and paste a block of code than to make up an example. I make up code when I feel that putting the code out there for the world might be bad. In this case I see no negatives so why not? – Jared Mar 08 '12 at 19:38
  • @phoog Most places in my code I do put the catch block for an EntityException, but I also use Elmah to log all my exceptions so I'm being notified of every exception regardless of how I'm filling out the catch block. This may not be the correct way to do it but it works for me at the moment and if I ever need the additional details that `Exception` doesn't provide than I go in and add it. On my list of things to do is a lot of code re-factoring, but they want the project asap so I'm having to cut corners where I can and noting where I need to go back and fix things once it's out there. – Jared Mar 08 '12 at 19:42
  • 1
    @Jared, just more for everyone else to have to read through, when it isn't relevant. – Jonathon Reinhart Mar 08 '12 at 22:17

4 Answers4

5

The later is better: it will avoid masking exceptions eventually thrown dy dispose. See this article.

J.N.
  • 8,203
  • 3
  • 29
  • 39
  • 1
    +1 for pointing this out: however, any Dispose that throws an exception is already "bad" in my book :( –  Mar 08 '12 at 05:38
  • Unless you explicitly want to catch errors thrown by the using statement. Something like using( FileStream fs = new FileStream(... can throw easily if the path is invalid or inaccessible, and may even be more likely to throw than the contents of your using block. – Denise Skidmore Jul 08 '13 at 20:18
2

It's really a matter of style and how narrow you want to keep the scope of db:

If the using is inside the try/catch block the db variable will only be accessible within the try portion.

If the using is outside the try/catch block it will be visible within the catch portion.

Regardless, the variable will be disposed of correctly because the using block is the equivalent of a try/finally.

Personally I would be wondering why you need to catch exceptions there at all and what, if anything, you are able to do with them.

Andrew Kennan
  • 13,947
  • 3
  • 24
  • 33
  • I frequently use the try/catch to set a status code for the response on my actions that are called through ajax. – Jared Mar 08 '12 at 19:47
1

using nests predictably with try/catch and Dispose will be called all on paths. Predictably means control always flows from inner -> outer scopes (for both Exceptions and normal flow return).

The question is then: when should the catch be executed in relationship to the Dispose and what should the scope of the catch be? The answer to this will vary by code but must obviously be "on the inside" if access to db is required and "on the outside" if code executed as part of the using* might be the source of the exception.

(Also, empty catch blocks are icky! I am assuming they are there "for demonstration purposes".)

Happy coding.


*Note that an outer-catch will catch exceptions thrown from new tsmtcowebEntities() or (as pointed out by J.N.) the Dispose, should any exist. (It is another topic entirely if it acceptable for either construct to throw an exception ;-) I prefer to catch exceptions as close to the source as possible and let exceptions I don't know how to deal with "bleed out" uncaught except in certain top-level constructs (e.g. event handlers).

  • I actually have them a few places in my code simply because I have Elmah set to catch any Exception. On my todo list is to go back through and re-factor a lot of code and my try/catch blocks are one of those areas as well as improve the error logging setup that I have. – Jared Mar 08 '12 at 19:45
0

I would suggest placing the try/catch within the using because regardless of whether or not an exception is throw you should dispose of types the Disposable entity container

Glenn Ferrie
  • 10,290
  • 3
  • 42
  • 73
  • I guess that was part of my question. I was 100% positive in the functionality of nesting the try/catch inside of the using. I was more unsure if a using statement could handle the inverse and still dispose of the object/resources... I have some code that I'm working on and it's currently both way. I'm trying to find out if I need to go through the code and ensure that the try/catch is always nested or not. You have confirmed what I originally expected though so I'll accept the answer! @GlennFerrieLive – Jared Mar 08 '12 at 05:08
  • `using` does its own try catch. The `dispose` function will always be called. – J.N. Mar 08 '12 at 05:10
  • 1
    -1 Dispose will be called regardless of the nesting. @Jared: using is compiled to a try-finally (not try-catch as J.N. said). Dispose is called in the finally block, so it is called whether or not the exception is caught or handled. – phoog Mar 08 '12 at 05:27
  • hwy - guy who gave me the (-1)... Do you think that the try catch should encapsulate the using block? what the @phoog ? – Glenn Ferrie Mar 08 '12 at 05:36
  • I gave -1 because your answer implies that if the using is placed within the try-catch, and an exception is thrown, that Dispose won't be called. That implication is incorrect. – phoog Mar 08 '12 at 05:38
  • that's doesnt answer my question... @phoog – Glenn Ferrie Mar 08 '12 at 05:39
  • @GlennFerrieLive what question? Do I think the try catch should encapsulate the using block? Not particularly, but in general there are cases where someone might want to enclose a using block in a try block. – phoog Mar 08 '12 at 05:49