0

Suppose I have this application:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            throw new SomeSpecificException("testing");
        }
        catch (SomeSpecificException ex)
        {
            Console.WriteLine("Caught SomeSpecificException");
            throw new Exception("testing");
        } 
        catch (Exception ex)
        {
            Console.WriteLine("Caught Exception");
        }
        Console.ReadKey();
    }
}

// just for StackOverflow demo purposes
internal class SomeSpecificException : Exception
{
    public SomeSpecificException(string message) : base(message)
    { }

    public SomeSpecificException()
    { }
}

And my required output is as follows:

Caught SomeSpecificException
Caught Exception

Is there a way to do this? Or is my design totally off base?

Background:

I am adding code to an existing code base. The code base catches Exception (generalized exception) and does some logging, removes files, etc. But I have a unique behavior I'd like to only happen when SomeSpecificException is thrown. Afterwards, I'd like the exception handling to pass to the existing Exception catch clause so that I do not have to modify too much of the existing code.

I am aware of checking for exception's type using reflection or some other runtime technique and putting an if statement in the Exception catching clause as per Catch Multiple Exceptions at Once but I wanted to get feedback on whether the above approach is possible.

Community
  • 1
  • 1
mlnyc
  • 2,636
  • 2
  • 24
  • 29
  • How are you expecting the code to print "Caught InvalidCastException"? There is no code that ever prints that, nor any code that ever throws that exception. – Servy Jan 15 '14 at 18:04
  • Sorry @Servy, edited and fixed expected output – mlnyc Jan 15 '14 at 18:05
  • 2
    You're not throwing a `SomeSpecificException`, but you still expect your program to say that it caught one? – Servy Jan 15 '14 at 18:05
  • @Servy - better? my bad I forgot to change the code everywhere when replacing InvalidCastException with SomeSpecificException – mlnyc Jan 15 '14 at 18:09
  • @JohnSaunders I did but forgot to change the code everywhere. Should be all fixed now – mlnyc Jan 15 '14 at 18:10

4 Answers4

4

You need to use two try blocks:

try {
    try {
        throw ...;
    } catch(SpecificException) {
        // Handle
        throw;
    }
} catch(Exception) {
    // Handle
}
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

Your approach will not work. The best you can do is to extract the code you want to have in common between the two handlers into a method, and have them both call the common method.

    try
    {
        throw new SomeSpecificException("testing");
    }
    catch (SomeSpecificException ex)
    {
        Console.WriteLine("Caught SomeSpecificException");
        CommonHandling();
    } 
    catch (Exception ex)
    {
        CommonHandling();
    }

private void CommonHandling() {
    Console.WriteLine("Caught Exception");
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • 1
    This doesn't scale well when there are more than two tiers. – Servy Jan 15 '14 at 18:06
  • What kind of "tiers" do you mean? It seems like the OP is looking for something like falling through in a `switch` `case`, only for exceptions. – John Saunders Jan 15 '14 at 18:09
  • By tiers I mean the depth of the hierarchy. If there is a depth of 3, or 4, this gets out of hand very quick. My interpretation was that, yes, the OP is looking for something equivalent to fall through. Of course, the question isn't entirely clear, so that's just my interpretation. – Servy Jan 15 '14 at 18:10
  • @Servy: true, but I don't know that his common code follows inheritance hierarchy. We only have two classes to judge from, so this is the general case. Of course, solutions for general cases don't necessarily fit all specific cases. – John Saunders Jan 15 '14 at 18:16
  • Sure, which is why it's not like I downvoted this; I merely made the comment that this won't scale well, should that happen to be the case some given reader is interested in. – Servy Jan 15 '14 at 18:17
0

Try this:

    try
    {
        try 
        {
            throw new InvalidCastException("testing");
        }
        catch (SomeSpecificException ex)
        {
            Console.WriteLine("Caught SomeSpecificException");
            throw new Exception("testing");
        } 
    }
    catch (Exception ex)
    {
        Console.WriteLine("Caught Exception");
    }
    Console.ReadKey();

This should avoid changing the existing code much. You are just adding an additional try directly inside the existing one.

Maximum Cookie
  • 407
  • 3
  • 6
0

If you really want it to work this was, I suppose you could so something with a switch statement

    try
    {
        throw new InvalidCastException("testing");
    }
    catch (Exception ex)
    {
        switch(ex.GetType())
        {
        case "SomeSpecificException":
            Console.WriteLine("Caught SomeSpecificException");
            goto default; //if I recall correctly, you need a goto to fall through a switch in c#
            break;
        default:
            Console.WriteLine("Caught Exception");
    }
    Console.ReadKey();
cost
  • 4,420
  • 8
  • 48
  • 80