Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I expose through COM an exception caught with structured exceptions handling?

My COM server implemented in Visual C++ uses a ton of other C++ code. That other C++ code sometimes wraps code in __try-__except and translates structured exceptions into custom C++ exceptions. This part I cannot change.

No method of my COM server should let those exceptions propagate through the COM boundary so it has to catch and translate them into HRESULTs. Those custom C++ exceptions contain the original error code which was obtained during translation - it's something like EXCEPTION_ACCESS_VIOLATION. The question is how I craft an appropriate HRESULT value so that the client has as much information as possible as to what happened (and perhaps decide to restart the server (and itself in case of inproc) after seeing an access violation).

Suppose it was EXCEPTION_ACCESS_VIOLATION which is defined in WinBase.h

#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION

and the latter is defined in WinNT.h

#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L)

I could use HRESULT_FROM_WIN32() to translate that code into HRESULT assuming that it was a Win32 error in the first place.

Do I use HRESULT_FROM_WIN32() here or do I use any other way to do the translation?

like image 278
sharptooth Avatar asked Sep 28 '22 04:09

sharptooth


1 Answers

You are supposed to return HRESULT code, where you choose appropriate code to indicate status of operation. It does not have to be a failure code, but you typically want to show something that satisfies FAILED(...) macro, e.g. E_FAIL, or DISP_E_EXCEPTION or HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION).

It is highly unlikely that callers compare against specific exception-related HRESULT, so specific failure code makes sense rather for diagnostic. Also, as you complete handling the exception before exiting from COM method, there is no need to return specific HRESULT code because no additional actions are required or necessary.

To provide additional information, it is possible to use ISupportErrorInfo, IErrorInfo and friends. Callers can retrieve free text description and many popular environments to this automatically, so for example .NET caller will have this additional information on exception message rather than standard message generated from HRESULT code.

ATL offers AtlReportError to wrap SetErrorInfo API, which also suggests on generating HRESULT code:

... If hRes is zero, then the first four versions of AtlReportError return DISP_E_EXCEPTION. The last two versions return the result of the macro MAKE_HRESULT( 1, FACILITY_ITF, nID ).

like image 151
Roman R. Avatar answered Oct 06 '22 19:10

Roman R.