1

I have the following code:

       try
       {
           retval = axNTLXRemote.IsUnitPresent(_servers[0].IPAddress, 1, _servers[0].RemotePort, _servers[0].CommFailDelay * 1000);
       }
       catch (COMException ce)
       {
            throw ce;
       }

Which gives me the followig warning which I want to get rid of:

CA2200 : Microsoft.Usage : 'Connect()' rethrows a caught exception and specifies it explicitly as an argument. Use 'throw' without an argument instead, in order to preserve the stack location where the exception was initially raised.

I have read the following The difference between try/catch/throw and try/catch(e)/throw e and I understand that the 'throw ce; will reset the stack trace and make it appear as if the exception was thrown from that function.

I want to simply change it to a 'throw' instead of a 'throw ce' which will get rid of the warning.

  1. What is the difference in the following catches:

       catch (COMException ce)
       {
            throw;
       }
    

    and

       catch (COMException)
       {
            throw;
       }
    
  2. Do I only need to have 'COMException ce' if I wish to somehow use the ce variable?

  3. Also, when I perform a 'throw' or 'throw ce', is it the calling function that will handle or catch it?? I'm a little unclear about this.

Community
  • 1
  • 1
Harry Boy
  • 4,159
  • 17
  • 71
  • 122
  • Good advice. Better advice is to just get rid of try/catch, it doesn't do anything useful. – Hans Passant Jun 06 '13 at 14:13
  • I have inherited a project which is riddled with try/catches so I'm trying to tidy up warnings etc. I can't get rid of all of them at this stage. – Harry Boy Jun 06 '13 at 14:16

3 Answers3

1

There is no difference in both cases, but only when exception variable should be used for stack/message etc.

So:

catch(ComException);

and

catch(ComException ex);

statements will produce similar MSIL, except local variable for ComException object:

.locals init ([0] class [mscorlib]System.Exception ex)
Dzmitry Martavoi
  • 6,867
  • 6
  • 38
  • 59
1

I'm sure someone will jump in with an uber-technical answer, but in my experience the answer to your first two questions is that there is no difference, and as you stated you'd only include ce if you intended to use it to write the stack trace to a log or display the message to the user or similar.

The throw will send the exception up the chain. That may be the calling method or, if your method has several nested try/catch blocks, it will send the exception to the next try/catch block that the current try/catch block is nested within.

Here are a couple good resources to check out if you want to read further on the subject:

Grant Winney
  • 65,241
  • 13
  • 115
  • 165
  • So if I look further up the chain (Or for another nested catch) and see nothing else that is using the ce variable then I know that I can safely remove it???? – Harry Boy Jun 06 '13 at 14:21
1
  1. The only difference is that with catch (COMException ce), you are assigning the exception to a variable, thereby letting you access it within the catch block. Other than that, it is in every way identical.
  2. I'm not sure what the question is here. If you want to access the exception object, you must give it a variable name in the catch clause.
  3. No matter how or where an exception is thrown, the exception will bubble up through the call stack to the closest catch block that matches.

Here's an example.

void Method1()
{
    try
    {
        Method2();
    }
    catch // this will catch *any* exception
    {
    }
}

void Method2()
{
    try
    {
        Method3();
    }
    catch (COMException ex) // this will catch only COMExceptions and exceptions that derive from COMException
    {
    }
}

void Method3()
{
    // if this code were here, it would be caught in Method2
    throw new COMException();


    // if this code were here, it would be caught in Method1
    throw new ApplicationException();
}
Michael Gunter
  • 12,528
  • 1
  • 24
  • 58