views:

115

answers:

8

let's say methodA and methodB will both throw a couple of types of exceptions, and some exceptions are of the same type, some are not, so what's the best practice to handle this?

style A:

void foo()
    {
        try
        {
            methodA();
        }
        catch (exceptionTypeA)
        {
            handleA;
        }

        try
        {
            methodB();
        }
        catch (exceptionB)
        {
            handleB;
        }
    }

style B:

void foo()
    {
        try
        {
            methodA();
            methodB();
        }
        catch (exceptionTypeA)
        {
            handleA;
        }
        catch (exceptionB)
        {
            handleB;
        }
    }
+4  A: 

It depends on your intentions.

If methodA can throw exceptionB (and vice versa), and you want those exceptions to be handled as well, use style B.

If you do not expect methodA to throw exceptionB (and vice versa), or are not prepared to handle it at this point, use style A to prevent exceptions being caught inadvertedly and hidden from the caller.

Thomas
+11  A: 

Neither is "better"; they're simply different. Depending upon what you do in your catch block, the first option will allow methodB to execute even if methodA throws an exception of type exceptionTypeA, while the second block requires that methodA succeed in order for methodB to be called.

Adam Robinson
what if methodA and methodB may throw same exception?
Benny
@Benny: That's not really the question though. I'm just pointing out that the two examples you provide are functionally different; you can't say one is "better" than the other, since they are not fundamentally the same.
Adam Robinson
@Adam, reword my question to make it clearer.
Benny
@Benny: I understand what you're saying, but the approaches are still different; even if `methodA` and `methodB` throw the same type of exception, the first example will still proceed to call `methodB` even if `methodA` throws a caught exception (unless you rethrow it or return from the method in the catch block). The *second* example does not do this; if `methodA` throws any kind of exception (caught or not), `methodB` will never be called.
Adam Robinson
A: 

I like method B better, but sometimes method A is necessary. For example if methodA and methodB could both throw the same exception, but you need to know which one threw it in the catch block.

Eric Petroelje
+2  A: 

In your particular case, it depends on what you want to do:

If you want to stop the execution wherever an exception occurs MethodA or MethodB then you go the second route.

If you want to execute MethodB after MethodA completes (successfully or not), then you go the first way.

Raj More
+1  A: 

Your sample code is not equivalent. In your first example A methodB() will always be executed while in sample B it won't be executed if A throws.

Depending on this different semantics you need to decide which "style" to use.

Johannes Rudolph
+1  A: 

It depends if exceptionTypeB does not inherit the exceptionTypeA.

So, generally speaking StyleA could be "preferable" if you are new to .NET and not sure what inherit from what.

In the Style B you need first catch the more particular exception, then more general one.

StyleB is more "performant", cause two try catch blocks are more resources and time consuming that a only one.

serhio
+1  A: 

The primary difference between the two examples is that in the second example, if methodA(); throws an exception, execution of methodB(); will not happen. In your first example both methodA(); and methodB(); will be executed, regardless of and failure on the part of methodA();. Therefore, it isn't a matter of styling, but rather a matter of expectation. If you EXPECT methodB(); to execute no matter what, then the first example is for you. If methodB(); should fail when methodA(); does, then example two is the way to go.

md5sum
+1  A: 

Depends, the code seems to imply that methodA and methodB will only throw exceptionTypeA and exceptionB repectively. Given that I would generally use the second method.

However, there are differences in behavior. If an exception occurs on methodA do you want methodB to execute? In the first example it will execute methodB even if an excpetion occurs in methodA. In the second example it will not.

I find the second example less cluttered and easier to read, but the functionality differences certainly more important.

Jim Reineri
Oops, soory for the added noise. I posted this answer before noticing that there were already some very good answers.
Jim Reineri
@JimR, thanks for answering anyway.
Benny