I have a .NET assembly which is invoked via COM Interop from a Delphi Host. I understand that any unhandled exception in the .NET code will be handled by the .net com interop framework and a correspoding HRESULT will be returned to the the COM host (delphi). Stack information is however lost during this Exception to HRESULT conversion.
The problem is that we would like to log all unhandled exceptions in .net code and I have not found any way to register a catch-all handler that is actually invoked whenever such an exception occurs.
I have tried:
but these are not invoked when running under COM Interop.
Is it possible to define some sort of handler/callback for unhandled exceptions for the COM Interop Framework? Or somehow hook into the process of converting a Managed Exception to an HRESULT so that the exception can be logged?
Thanks!
I think the best option here would be to use something like
void ComClassMethod()
{
try { ... }
catch (Exception ex)
{
/* store the ex in the object */;
throw;
}
}
everywhere in your C# methods exposed to COM.
Alternatively, you could handle AppDomain.CurrentDomain.FirstChanceException
and store the last 1st-chance exception, which you could also expose to COM.
However, pay special attention if your COM object support muliti-hreading (note, most .NET COM objects are free-threaded). In this case, you'd need to maintain a map between threads and their corresponding most-recent exceptions, either per object or globally via System.Threading.ThreadLocal<T>
(decide what suits your logging requirements better).
Updated, I've been thinking, there has to be a better way of doing this. And there is one, indeed, as explained here in Adam Nathan's excellent ".NET and COM: The Complete Interoperability Guide" book. I'm not sure I can copy/paste an exact quote from the copyrighted material, but the idea is the following:
ISupportErrorInfo
.IErrorInfo
object - can be retrieved on COM side via GetErrorInfo
API._Exception
COM interface. _Exception
to get all the details, including _Exception.StackTrace
.This seems to be exactly what you're looking for.