views:

144

answers:

4

I'm trying to write some code that catches a particular exception and throw a more useful one for something higher up the call stack to deal with but also catch more general exceptions and handle them.

The code is something like this:

try
{
    // Do stuff
}
catch (SomeException e)
{
    throw new SomeExceptionWithContextInfo();
}
catch (Exception e)
{
    // Handle unexpected exception gracefully
}

The problem I'm having is that the general exception is catching my new exception. is there a way to avoid this?

My current solution involves checking the type of the exception and throwing it again if it's type is what I just created.

+3  A: 

The code you posted is the way to do it (catch for more specific exception must appear first).

I suggest looking again at the code, as either they are not in that order, or the code isn't actually throwing that exception type.

Here is a link on msdn about try-catch: http://msdn.microsoft.com/en-us/library/0yd65esw(VS.80).aspx

eglasius
+6  A: 

The code you've posted should work, as shown in this test app:

using System;

class OtherException : Exception {}

class Test
{
    static void Main(string[] args)
    {
        try
        {
            Foo();
        }
        catch (OtherException)
        {
            Console.WriteLine("Caught OtherException");
        }
    }

    static void Foo()
    {
        try
        {
            string x = null;
            int y = x.Length;
        }
        catch (NullReferenceException)
        {
            throw new OtherException();
        }
        catch (Exception)
        {
            Console.WriteLine("Caught plain Exception");
        }
    }
}

This just prints "Caught OtherException" not "Caught plain Exception". Are you sure you don't have a nested try block in your real code? Could you post a short but complete example which shows your problem?

Do you really need to catch Exception in your method though? That's very rarely a good idea.

Jon Skeet
That's correct, but it there is no try/catch in the Main method, then a plain Exception will be caught, that's what is happening I guess.
Groo
If there is no try/catch in the Main method, the application will abort because the exception won't be handled at all.
Jon Skeet
My bad it turns out it was a different exception
Omar Kooheji
A: 

Don't catch general exceptions might be the answer? Find out which Exceptions that can be thrown and catch them separately.

try { // Outer try/catch
    DoSomething();

    try {
        /* */
    } catch(NotGeneralException e) {
        /* */
    } catch(AnotherNotGeneralException e) {
        throw new SomeOtherException("Exception message");
    }
} catch(SomeOtherException e) {
    /* */
}

Alternatively only catch a general exception and rethrow SomeOtherExcepion

try {

} catch(Exception e) {
    throw new SomeOtherException("Exception message");
}
Björn
I didn't go as far to post a sample app as Jon, but catch work as intended, no need for workarounds - there is surely something else with that code
eglasius
+2  A: 

You're doing it right. The general exception will not catch the specific one.

Tor Haugen