Share via


Get "Right" HResult (Error ID) from Exception

Question

Monday, March 3, 2008 7:35 PM

Hi!.

I am new in this forum, so I don't know If this thread should be in this section or not. Anyway, I have got one question for experts.

Recently I am creating my own SDK in C# and Java. In my SDK I create an exception library for the SDK (C#).

Well, What I want to do is to create my own error phrases instead the common error phrases given by the Exception classes.

What I did, is the next:

I enclose the code in a try and pass throw Exception catch. I spot that this Exception got and Error Code (HResult). I think that this code is unique. So What I need to do , is to get that code and pass it to the constructor of a new instance of my Exception class. Then my exception class, take that error and return an especify phrase for this error.
But.... When I do this, I have always got HResult = -2146233088, always the same error code. I tryed with different Exception errors, but it always returns the same Error code... Why?, How can I get the unique error code for each error Exception. Here I pass some piece of code the clarify What I want to do.

.....

        public string AbrirConexion()
        {
            try
            {
                _Conexion.Open();

                return Properties.Settings.Default.strOpenConection.ToString();
            }
            catch (Exception excepcion)
            {
                DataBaseExceptions ex = new DataBaseExceptions(excepcion);
               
                return ex.Mensaje;
            }
        }

......

.....

       public enum DataBaseExceptionsCodigo : int
       {

FalloConexion    = -2146233025
......

       }

........
public class DataBaseExceptions : Exception

 {
        private DataBaseExceptionsCodigo ExcepcionCodigo;

        public DataBaseExceptions(Exception inner) : base(inner.Message , inner)
        {

   //Here I always get base.HResult = -2146233088 !!!!!

            this.ExcepcionCodigo = (DataBaseExceptionsCodigo)base.HResult;   //or this.HResult    
        }

        private string this[DataBaseExceptionsCodigo indice]
        {
            get
            {
                switch (indice)
                {

case DataBaseExceptionsCodigo.FalloConexion:

return "MyPhrase..blablabla";

                }
           }

        public string Mensaje
        {
            get
            {
                return this[ExcepcionCodigo];
            }
        }
}
........

I just Cut and paste some pieces of code (the most important), to clarify my intentions. All I need is to get the identifier (ID) of this error and pass it through the constructor of my class. I have tried several things, and I think that HResult is the best solution for me (of course _COMPlusExceptionCode is better, but is non Public).

Many thanks in Advance, and sorry for my horrible English written...as you can see I am not English

All replies (8)

Monday, March 3, 2008 7:47 PM

-2146233088, I assume, is the default HResult for exceptions.  When you call "this.HResult", that is what you get because you never specified the HRESULT for the exception you just created.  Its not automatically inherited from the inner exception.  You need to call this.InnerException.HResult (or whatever your language's version of it is).


Tuesday, March 4, 2008 12:06 AM

That for awnser Nimrand.

That was my first try. If I pass -- inner -- to the base constructor, then I need to call (as you awnser) this.InnerException.Hresult. But, InnerException returns a new exception based on the current exception, which is not the same instance that Exception inner, and only the classes which extends from the inner Exception instance can access to its HResult, because HResult is protected. So If you try to type this.InnerException.(here it does not appear HResult).

        public DataBaseExceptions(Exception inner) : base(inner.Message , inner)
        {
 The old line            this.ExcepcionCodigo = (DataBaseExceptionsCodigo)this.HResult;     
 The new line           this.ExcepcionCodigo = (DataBaseExceptionsCodigo)this.InnerException.???     
       }

Do I explain myself?. Sorry I am terrible explaining a issue, I know. I think there is another solution, but right now I do not know which is it.

Anyway you answer give me another idea.... Thanks a lot. If I did not got it, I will put my advances for this new idea.


Tuesday, March 4, 2008 12:32 AM

Well that is what I get.

In the debugging inspection, When I watch the Exception inner, it has inside of its non public members, the HResult value, and this value is -2147352558 (different form the default one), and this value is exacly what I want. The problem is that I do not know how to access and get it. I know that this is the value that I want, because I tried with different errors and all contains different values (the values are ID's), and these ID's would be perfect for my intentions.

I will be waiting for someone can help me.

Many Thanks


Friday, March 14, 2008 5:08 PM

As I can see, noone knows how to solve it. Well I think I will spend more time investigating and If i get the solution i will put it here. Meantime I will be waiting if someone can solve it before I do.


Friday, March 14, 2008 6:33 PM

Yeah, I understand the problem.  I thought that HResult was public, but I guess I was wrong.  There seems that the ought to be a way to retrieve the HResult of an exception without inheriting from it.

 


Thursday, February 12, 2009 1:44 AM

I know this thread has some age on it, but I was having the same problem and decided to find a solution.  Here is what I came up with.  It is in C++, but you can easily convert to c#.

int hr = (int)ex->GetType()->GetProperty("HResult",  
          System::Reflection::BindingFlags::Instance |  
          System::Reflection::BindingFlags::NonPublic)->GetValue(ex, nullptr); 

Thursday, June 24, 2010 8:19 PM

I'm surprised that actually worked. You probably just saved me hours of beating my head against the wall.

Here's the C# version:

int hr = (int)e.GetType().GetProperty("HResult",
  System.Reflection.BindingFlags.Instance |
  System.Reflection.BindingFlags.NonPublic).GetValue(e, null);

Thursday, June 24, 2010 8:53 PM | 1 vote

hr = Marshal.GetHRForException(e);