0
try {...}
catch (InvalidDataException ex){...}

can catch any instance of InvalidDataException class raised in the try block.

When it is possible that the try block contains several places which can all raise instances of InvalidDataException class, is it possible to catch a particular instance?

Thanks.

Tim
  • 1
  • 141
  • 372
  • 590
  • There are a few ways you could do this - multiple try blocks, throwing different exception types, filtering on the message - but this seems like an XY problem to me. Can you provide a more complete example of a case where you want to do this? – BJ Myers Jun 02 '17 at 23:57
  • Generic Exception vs custom Exception classes? IF its Generic,there's no way of differentiating which instance, the only way around it, is to create custom Exception classes that inherits from `InvalidDataException` with a particular flag or enum, when an exception occurs, throw that `InvalidDataException` with said enum. – t0mm13b Jun 02 '17 at 23:57
  • @BJ: I am expecting some method to throw an exception in a unit test method which tests the method. So I call the method among other things in the `try` block, and need to catch any exception that the method may raise. But I can't rule out if another exception of the same class can be thrown from other lines of code in `try` block, so I need to differentiate which exception instance is thrown, and only catch the one thrown by the method being tested. – Tim Jun 03 '17 at 00:02
  • @t0mm13b Thanks. Could you post the specifics in a reply so that I can understand it better? – Tim Jun 03 '17 at 00:08
  • a bit slow, but you can get the stack trace https://stackoverflow.com/a/43231760/1383168 – Slai Jun 03 '17 at 00:19
  • If you're testing, your environment should be mocked out in a way that any exception thrown is a well-known and expected exception (that is, one that you can specifically check for using `Assert.Xxxx` or some similar testing function). This whole idea of looking for a particular exception instance sounds like an X-Y problem and my advice would be to avoid doing this using any of the suggested workarounds. – xxbbcc Jun 03 '17 at 02:18

3 Answers3

1

Basically you could do something like

try {...}
catch (InvalidDataException ex)
{
   if (ex == myInstance) {
      // do something
   } else {
       throw;
   }
}

But I would highly advise against it. You should not control your program flow using exceptions.

adjan
  • 13,371
  • 2
  • 31
  • 48
  • Doesn't this require that `myInstance` is an exception declared outside of the `try` block before it is even raised? That seems really strange. – BJ Myers Jun 02 '17 at 23:58
  • @BJMyers Yes, that's why the whole idea is a bad one. – adjan Jun 03 '17 at 00:01
1

If I understand correctly - you have a try block. Within that try block there are several similar operations that might throw an InvalidDataException. You want to catch some of those but not catch others.

As suggested this is likely an XY problem, but here's how to literally do what you are saying in C# 7. I'm not recommending this, just literally answering the question.

bool catching = false;
try
{
    catching = true;
    // now exceptions are caught in the catch block.

    catching = false
    // now exceptions aren't caught - they are thrown to the calling method.

}
catch (InvalidDataException ex) when (catching)
{

}
Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
1

This is a simple example

[Serializable]
    public class MyException : Exception
    {
        public MyException() { }
        public MyException( string message ) : base( message ) { }
        public MyException( string message, Exception inner ) : base( message, inner ) { }

        protected MyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context ) : base( info, context ) { }
    }

    class Program {
        static void Main(string[] args) {
            try{
                throw new MyException("Whoops#1");
                //throw new MyException("Fubar#2");
            }catch(MyException myEx){
                string aExMsg = myEx.Message;
                if (aExMsg.Contains("#1")){
                    Console.WriteLine("Whoops was caught");
                }
                if (aExMsg.Contains("#2")){
                    Console.WriteLine("Fubar was caught");
                }
            }catch (Exception ex){
                throw;
            }
            Console.Write("Press <ENTER> to continue...");
            Console.ReadLine();
        }
    }

Uncomment the line //throw new MyException("Fubar#2"); and run it, the catch block for MyException will trap the error, examine the contents of the Message class, looking for a specific clue, and thus can get an instance.

However, it is imperative to note, this is not exactly a good way of handling exceptions, or controlling the flow of code by doing this. Don't care or even go down the road in determining what instance is it - why? too much time expended there! Just look at the Message part for a clue and leave it at that.

Exceptions, are for a reason, when a error condition occurs, two outcomes - to catch them or quietly discard (bad!).

Looking at the above example code, if that is part of a processing data in some shape or form, does it impact the soon-to-be-yet-executed dependency class or method?

Set off a couple of trip switch flags for benefit of soon-to-be-yet-executed dependency class or method in such a way, that when further code beyond gets executed; it will see the trip switch flag that is set previously, to skip out on bunch of code, knowing that an error occurred previously, will make things worse.

Finally, gracefully log it, inform the operator Just don't use the word ERROR in some popup or component that the operator will see, it will just give them a un-needed panic and stress.

t0mm13b
  • 34,087
  • 8
  • 78
  • 110