views:

903

answers:

9

I'm bored with surrounding code with try catch like this..

try
{
    //some boring stuff
}
catch(Exception ex)
{
    //something even more boring stuff
}

I would like something like

SurroundWithTryCatch(MyMethod)

I know I can accomplish this behaviour by creating a delegate with the exact signature of the function, but creating a delegate for all the methods in my application it's just not an option.

I can also do this by injecting IL code but this is expensive in terms of performance as it creates an wrapper assembly around mine.

Any other valid ideeas?

+3  A: 

You can try to use some null validiation instead. I can take a LINQ to SQL example:

var user = db.Users.SingleOrDefault(u => u.Username == 3);

if (user == null)
    throw new ArgumentNullException("User", "User cannot be null.");

// "else" continue your code...
stiduck
Actually you should never throw `NullReferenceException`. This is reserved for the runtime. You could try though `ArgumentNullException`
Bogdan Maxim
Sorry. I wrote that in a hurry. I will change it right away. Thanx :)
stiduck
+2  A: 

Perhaps you're treating exception handling as error codes via a different syntax? So don't try/catch. Let the exception propagate upwards.

Scott Weinstein
A: 

You could try creating a monad builder for this. You would be doing the same thing but it would hopefully look prettier.

Here's a link to an Error monad.

fung
A: 

I'm not sure for C#, but in Java-land you could define and interface with all the methods, and then hide it under a proxy object. You could run away with writing even more code by defining something like:

ExceptionCatcher.catchAll(new Runnable() {
  public void run() {
     //run delegate here
     MyMethod();
  }
});

and catchAll() will just call the runnable and wrapping a try-catch block around it.

However, I think what you really want is a language that has got nice [closure support]. Using closures, doing what you want is extremely easy.

Roopinder
Fortunately, C# *is* a language with nice closure support :) (The question doesn't state language, but it can be inferred by the code and mentioning IL and delegates.)
Jon Skeet
+16  A: 

Firstly, it sounds like you may be using try/catch too often - particularly if you're catching Exception. try/catch blocks should be relatively rare; unless you can really "handle" the exception, you should just let it bubble up to the next layer of the stack.

Now, assuming you really do want all of these try/catch blocks, why is it not an option to create a delegate? With anonymous methods and lambda expressions, as well as the Func/Action delegates in the System namespace, there's basically very little work to do. You write:

public void SurroundWithTryCatch(Action action)
{
    try
    {
        action();
    }
    catch(Exception ex)
    {
        //something even more boring stuff
    }    
}

and then your SurroundWithTryCatch(MyMethod) will work fine, if it takes no paramaters.

Alternatively, if you don't want to call a different method, just write:

public void MyMethod()
{
    SurroundWithTryCatch(() => 
    {
        // Logic here
    });
}

If you need to return from the method, you can do:

public int MyMethod()
{
    SurroundWithTryCatch(() => 
    {
        // Logic here
        return 5;
    });
}

with a generic overload of SurroundWithTryCatch like this:

public T SurroundWithTryCatch<T>(Func<T> func)
{    
    try
    {
        return func();
    }
    catch(Exception ex)
    {
        //something even more boring stuff
    }    
}

Most of this would be fine in C# 2 as well, but type inference won't help you quite as much and you'll have to use anonymous methods instead of lambda expressions.

To go back to the start though: try to use try/catch less often. (try/finally should be much more frequent, although usually written as a using statement.)

Jon Skeet
@Jon ahh you beat me to it..DAM YOU ;)
Nathan W
+2  A: 

It is not something you usually want to "get rid of".

If you are just toying around, playing with some stuff, not really care about quality for one reason or another, you can just let every method throw every exception. Here's my latest example, from a mini-project I'm working on right now:

public static void main(String[] args) throws ParseException, IOException, InterruptedException {

Many other method also throws a lot of methods, for example the IOException "hides" a FileNotFoundException etc. This means that if anything goes wrong, the application crashes. But that's okay, I actually want this program to display a stacktrace and just stop.

Later on I can copy the bits I'm actually going to use in the final product, and implement proper exception handling, which lead me to...

If you DO care about the quality of your application, you do not want to "get rid of" the exceptions, you want to use them properly.

Theres an introduction here: Lesson: Exceptions (The Java™ Tutorials > Essential Classes) - but you should read more about it, good design-patterns etc.

myplacedk
+2  A: 

For me I looks like you are asking for aspect oriented programming. I think you should take a look at PostSharp.

Martin Moser
thanks, I think that's what I wanted, have you used this approach in a production code?
Razvan Dimescu
+4  A: 

Aspect Oriented Programming could also help you, but this may require that you add libraries to your project, postsharp would help you in this case. See this link http://doc.postsharp.org/1.0/index.html#http://doc.postsharp.org/1.0/UserGuide/Laos/AspectKinds/OnExceptionAspect.html#idHelpTOCNode650988000

pablito
hey, that's exactly what I wanted, do you have any experience with this? Would you recommend using it instead of the classic way?
Razvan Dimescu
I have used this only for learning purpuses, not on a real project. I personally like this concept very much.
pablito
A: 

If you're using Java, you have RuntimeExceptions, which are exceptions that mean something has gone wrong that you can't be expected to recover from. Look it up. Start here: http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html

For example, Spring's Data Access bits throw various RuntimeExceptions when things go wrong. Dealing with them is optional.

tunaranch