We have a very large application that we are moving to C# over the course of several years. There is still a lot of "legacy" C++ code that was originally making heavy use of COM; especially ADO Recordsets. We now have all of the C++ projects compiled with /clr and have some of the C++ code using .NET methods and calling our C# libraries. Due to how the original C++ code was written (i.e. every method returns a "result code"), every method has a try/catch. The original pattern used was:
try { } catch (_com_error& e) { } catch (...) { }
With that pattern, if the code attempts to access a recordset field that doesn't exist (e.g. pors->Fields->GetItem(99)->Value), the exception is thrown and caught in the "catch (_com_error& e)" block and e.Error() = -2146825023 and e.Description = "Item cannot be found in the collection corresponding to the requested name or ordinal.".
Since we now have C++ code using .NET, I would like to change the pattern to:
try { } catch (SEHException^ seh) { } catch (Exception^ e) { }
With this pattern, sample scenario, the exception is caught (as I expect) in the "catch (SEHException^ e)" block but the e.HResult = -2147467259 and e.Message = "External component has thrown an exception.". The upside of catching SEHException is that I get an accurate Callstack I can log (something we didn't have before). However, as you can see, we've lost the detail of what the underlying issue was ("Item cannot be found in the collection corresponding to the requested name or ordinal.").
Is there any way for us to obtain that original HResult and/or error description in the catch SEHException? (Note, I also tried adding a "catch (COMException^ com)" block but it never got hit.
Thanks,
Brad