Getting full exception details

When an exception is thrown on my Panda in the debug console I see more details than if I use a catch and ex.StackTrace. The reason I care is because I am letting the device run unattended and logging errors to an SD card. But when I write the exception to the log it doesn’t have the initial part of the error where it will list something like “Exception System.OutOfMemoryException - CLR_E_OUT_OF_MEMORY (5)”. I don’t see any additional properties, is there any way I can get that info also?

Exception object has everything in it. Put breakpoint in the exception handling code and then examine (Shift+F9) properties of the object. This will give you an idea of what properties to log to achieve the level of details you want.

Are you writing ex.ToString() or ex.Message? ex.ToString()should have more info. As Arch says, if that don’t cut it, then need to enumerate the class.

I had ex.ToString() at first because that is what I am used to using in the non-micro .NET frameworks. But it was printing out the standard object.ToString() implemention, i.e. just giving me “System.IOException” for example. StackTrace has more info, Message just has the exception name (“System.IOException”) and nothing has the ALL_CAPS_ERROR which you see as the first line of the debug output when it occurs.

Just to avoid any debate, here is a concrete example with some sample code:

        try
        {
            var x = 9;
            var t = 15 / (x - 9);
        }
        catch (Exception ex)
        {
            Debug.Print(ex.ToString());
        }

ex.ToString() = "System.Exception"
ex.Message = "Exception was thrown: System.Exception"
ex.StackTrace = “HelloWorld.HelloWorld::Main”

Debug output to console (what I need programmatically) is the first line of the below message:
#### Exception System.Exception - CLR_E_DIVIDE_BY_ZERO (1) ####
#### Message:
#### HelloWorld.HelloWorld::Main [IP: 000c] ####

Division by zero is a bad example. Change it to:


                var x = new byte[2];
                var y = x[2];

and you will get a System.IndexOutOfRangeException, not System.Exception. There is no DivideByZeroException as in regular .NET so a base Exception is thrown. I aslo don’t know how to get specific information about events that are accumulated as base Exception and only details are available in console output.

This has the exact same behavior:

        try
        {
            var x = new byte[2];
            var y = x[2];
        }
        catch (Exception ex)
        {
            Debug.Print(ex.ToString());
            Debug.Print(ex.Message);
            Debug.Print(ex.StackTrace);
        }

outputs:

System.IndexOutOfRangeException
Exception was thrown: System.IndexOutOfRangeException
HelloWorld.HelloWorld::Main

while the first line in the console with the error number (shown below) is not in any of those

#### Exception System.IndexOutOfRangeException - 0xa9000000 (1) ####

This particular exception tells you most of what you need to know but unfortunately the one I am getting (an IO exception) doesn’t give me as much information in the name alone as this one so I need that first line to tell me (hopefully) what the real issue is.

Here is a helper extension class that will give you the name of HRESULT code inside of an exception (CLR_E_INDEX_OUT_OF_RANGE, CLR_E_DIVIDE_BY_ZERO, etc.)

http://code.tinyclr.com/project/279/exception-extension-to-get-hresult-name/

Edit: Updated link:

https://www.ghielectronics.com/community/codeshare/entry/218

1 Like

Added already! Awesome.

Excellent, that is very helpful. Did you come up with this using Reflector to look at how the framework did it?

Also a good example of an extension method and reflection which I hadn’t seen in .NET Micro yet… Thanks!

No I didn’t use the Reflector. This is part of the native (c++) code of the framework. I just knew where the constants are defined and made them available through the extension.

We have several extension examples and at least one using reflection on “fezzer”.

+1.

It would seem a high-road solution may also be in order. A special “helper” could be used on the VS side so that MF side could save space. When the MF side throws exception, the VS side does table lookup for detail. Project ErrorTable can be extented for user defined exceptions. Not sure if this could just be a VS add-in or deeper.

Yes, but wouldn’t it limit the use of that functionality only when you are running under VS?

Wow, three years later and this thread is still incredibly useful.

Thanks @ Architect - Gene

@ Gene - You are welcome!