34
try
{
     object result = processClass.InvokeMethod("Create", methodArgs);
}
catch (Exception e)
{  
    // Here I was hoping to get an error code.
}

When I invoke the above WMI method I am expected to get Access Denied. In my catch block I want to make sure that the exception raised was indeed for Access Denied. Is there a way I can get the error code for it ? Win32 error code for Acceess Denied is 5. I dont want to search the error message for denied string or anything like that.

Thanks

iandotkelly
  • 9,024
  • 8
  • 48
  • 67
Frank Q.
  • 6,001
  • 11
  • 47
  • 62
  • 3
    Run the code, put a break point in your catch block, and use the debugger to look at the exception and see what information you have. – Joel Coehoorn Aug 01 '11 at 00:03
  • Alternatively, you could run the code without bothering to debug and print out the Exception type with GetType(). But Joel's answer will also do the trick for sure. – KyleM Aug 01 '11 at 00:07
  • You should only catch the exact type of exception you expect; catching `Exception` is almost always a bad code smell. – Bevan Aug 01 '11 at 01:06
  • @Bevan catching `Exception` is almost always good idea. Because you don't have to show a message at once — an every class shouldn't know does the app works with GUI or terminal. So you just have to save an exception ID to show it in a far far away. No need to catch every exception exclusively to do the same thing. At least it was the way I worked in C++. Now I'm work with C#, but don't see a reason that could make here a difference. – Hi-Angel Oct 03 '14 at 15:26

6 Answers6

49

You can use this to check the exception and the inner exception for a Win32Exception derived exception.

catch (Exception e) {  
    var w32ex = e as Win32Exception;
    if(w32ex == null) {
        w32ex = e.InnerException as Win32Exception;
    }    
    if(w32ex != null) {
        int code =  w32ex.ErrorCode;
        // do stuff
    }    
    // do other stuff   
}

Starting with C# 6, when can be used in a catch statement to specify a condition that must be true for the handler for a specific exception to execute.

catch (Win32Exception ex) when (ex.InnerException is Win32Exception) {
    var w32ex = (Win32Exception)ex.InnerException;
    var code =  w32ex.ErrorCode;
}

As in the comments, you really need to see what exception is actually being thrown to understand what you can do, and in which case a specific catch is preferred over just catching Exception. Something like:

  catch (BlahBlahException ex) {  
      // do stuff   
  }

Also System.Exception has a HRESULT

 catch (Exception ex) {  
     var code = ex.HResult;
 }

However, it's only available from .NET 4.5 upwards.

Preet Sangha
  • 64,563
  • 18
  • 145
  • 216
  • Since this question is kinda old, this is just a reminder for people who would like to use this answer: For .NET 3.0, 3.5 and 4.0 you will have to use reflection to get the value of the HResult property as it is marked protected. Source: http://stackoverflow.com/questions/15462675/how-can-i-get-the-error-number-instead-of-error-message-in-an-exception-in-c – curiousBoy Sep 29 '14 at 17:16
5

Building on Preet Sangha's solution, the following should safely cover the scenario where you're working with a large solution with the potential for several Inner Exceptions.

 try
 {
     object result = processClass.InvokeMethod("Create", methodArgs);
 }
 catch (Exception e)
 {
     // Here I was hoping to get an error code.
     if (ExceptionContainsErrorCode(e, 10004))
     {
         // Execute desired actions
     }
 }

...

private bool ExceptionContainsErrorCode(Exception e, int ErrorCode)
{
    Win32Exception winEx = e as Win32Exception;
    if (winEx != null && ErrorCode == winEx.ErrorCode) 
        return true;

    if (e.InnerException != null) 
        return ExceptionContainsErrorCode(e.InnerException, ErrorCode);

    return false;
}

This code has been unit tested.

I won't harp too much on the need for coming to appreciate and implement good practice when it comes to Exception Handling by managing each expected Exception Type within their own blocks.

Thomas N.
  • 61
  • 1
  • 2
  • Small improvement in C# 6, you can change your first if statement to the bottom line. The first part checks for null, and fails the if condition when `winEx == null`. Then it safely checks the `ErrorCode` property without throwing a null exception. `if (winEx?.ErrorCode == ErrorCode)` – Andrew S Jun 23 '17 at 22:01
4

You should look at the members of the thrown exception, particularly .Message and .InnerException.

I would also see whether or not the documentation for InvokeMethod tells you whether it throws some more specialized Exception class than Exception - such as the Win32Exception suggested by @Preet. Catching and just looking at the Exception base class may not be particularly useful.

iandotkelly
  • 9,024
  • 8
  • 48
  • 67
0

I suggest you to use Message Properte from The Exception Object Like below code

try
{
 object result = processClass.InvokeMethod("Create", methodArgs);
}
catch (Exception e)
{  
    //use Console.Write(e.Message); from Console Application 
    //and use MessageBox.Show(e.Message); from WindowsForm and WPF Application
}
-1

Another method would be to get the error code from the exception class directly. For example:

catch (Exception ex)
{
    if (ex.InnerException is ServiceResponseException)
       {
        ServiceResponseException srex = ex.InnerException as ServiceResponseException;
        string ErrorCode = srex.ErrorCode.ToString();
       }
}
GadgetNC
  • 159
  • 3
  • 4
-1

catch (Exception e) { if (e is MyCustomExeption myEx) { var errorCode = myEx.ErrorCode; } }

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 10 '23 at 10:33
  • Can you explain what does this do differently than all the other answrers posted here already? – General Grievance Feb 14 '23 at 14:34