Yuan
Yuan

Reputation: 2800

C# try catch pattern help

We always need to try catch in our code and it becomes ugly like

public void foo()
{
  try
  {
    DoSomething();
  }
  catch(Exception e)
  {
     //do whatever with e
  }
}

public int FooReturnInt()
{
  try
  {
     return IntAfterSomeCalculation();
  }
  catch(Exception e)
  {
    //do exactly whatever with e as foo()
  }
}

Imagine we have a huge class with many public functions like this and we have to apply same try catch in every single function.

Ideally, since the try catch part is identical, and we can pass down Func<> as parameter to a helper function which does something like

public void TryCatch(Func<something> theFunction)
{
  try
  {
    theFunction();
  }
  catch(Exception e)
  {
    //processthe common exception        
  }
}

Then I'd imagine this would tidy up my code alot, the now the problem is how to properly write this function? The return type of this function is depended on the return type of theFunction.

Upvotes: 10

Views: 6707

Answers (5)

Henk Holterman
Henk Holterman

Reputation: 273864

There are three reasons to use a catch block:

1 Because there could be an exception.

That is the wrong reason.

2 Because you can somehow handle the Exception.

This is the right reason.

3 Because you want to Add and/or Hide details

This catch & wrap , involves a re-throw and is not really a catch.

The main idea here is that programmers unfamiliar with exception handling tend to use (way) too much catch blocks. You seem to fall in this category.

Upvotes: 8

Paul Sasik
Paul Sasik

Reputation: 81567

Though you can use helper/wrapper methods, you should not be structuring your code this way. It looks like you're trying to use try/catch like the old system of returned success/error codes. Your public functions should actually be throwing exceptions of the appropriate type and the consumer of your API ought to use try/catch at some level to manage the exceptional conditions.

The try/catch exception mechanism was designed to free developers from having to chain return codes from deep within code by allowing exceptions to "percolate up" the call stack until a handler was found. (The only time you see an exception is when it's unhandled by any method in a chain of calls.) In any case, here's a decent place to start on this topic.

And here is a "rules of thumb" blog post that will be easier to digest than the MSDN article. And another link with even more abbreviated content.

Excerpt from previous link:

  1. Don't catch Exceptions you can't handle
  2. Never swallow exceptions
  3. Your code should have more Try/Finally (or using) than Try/Catch
  4. Never throw/catch new Exception() (too broad a class) instead try to thow\catch a more derived exception (ArgumentNullException, etc)
  5. When re-throwing an exception use throw; as opposed to throw ex; this will keep the stack trace from being reset
  6. When writing a library vs an application I will never catch an expectation unless I can DEFINITELY handle it
  7. Use logic to control the flow of the program rather than exceptions, check for NULL rather than catch ArgumentNullException

Number 6 applies in your situation directly.

Upvotes: 7

Remoh
Remoh

Reputation: 134

Do you REALLY need to catch exceptions in every method? It's okay for a method to throw an exception as long as it's being handled "somewhere".

Take a good look at the architecture of your application and ask if there are points where it makes sense for exceptions to "bubble-up" to. Handle them there instead.

Upvotes: 0

Davide Piras
Davide Piras

Reputation: 44605

in my opinion having all the try catch in all methods is not ugly, and is not something to try to avoid. Do not assume that the catch block will always do the same, in some cases will log and throw, in other cases will handle the exception, in other cases you will not need catch at all.

if you do always in the way you are thinking to do you might even mess-up the stack trace and the log file could then help you less to find out the real bugs.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1504182

If you really think this is needed, you could use:

public T TryCatch<T>(Func<T> theFunction)
{
  try
  {
    return theFunction();
  }
  catch(Exception e)
  {
    // You'll need to either rethrow here, or return default(T) etc
  }
}

However, I would generally advise against it. Are you really sure you need the try/catch blocks in all of these methods? Generally there shouldn't be many try/catch blocks unless the catch just wraps the exception and rethrows... and even that's rarer in C# than it is in Java, for example.

You should usually catch an exception when you can either genuinely handle it gracefully or you need to prevent the process from blowing up just because one request failed (for example). I tend to write very few catch blocks - it's relatively rare that I can really recover from errors :)

This approach is going to lead to a significantly harder time debugging, I suspect. It may still be worth doing, but you should carefully consider the pros and cons first.

Upvotes: 20

Related Questions