I'm trying to return a detailed error to VB6 using CComCoClass::Error, but it seems I can only return an error code /or/ a message - but not both.
return Error(_T("Not connected"), __uuidof(IMyInterface), HRESULT_FROM_WIN32(ERROR_CONNECTION_INVALID));
results in a generic "Method 'Request' of object 'IMyInterface' failed" error message in Err.Description on the VB6 side (but ERROR_CONNECTION_INVALID in Err.Number), while
return Error(_T("Not connected"));
results in the appropriate error message, but a generic error code in Err.Number. How can I get the best of both worlds?
You can't, this appears to be by design. Details further below, but in short you have three options:
Method '~' of object '~' failed
".
For the task at hand it boils down to two choices:
The VB runtime seems to offer only very restricted handling in regard to COM errors. This is likely for historic and/or technical reasons specific to the way VB has been implemented and not of particular interest here (keywords would be IDispatch only vs dual interface and ActiveX as a 'subset' of COM).
While I've been unable to surface an explicit specification for the behavior outlined above one can figure it from digging through other sources:
From the KB article justadreamer pointed out already:
[...] a call is made to the GetErrorInfo method to retrieve the available error information. The runtime then determines whether bstrDescription has a value other than NULL. If the runtime finds a value other than NULL, [...], the raw HRESULT value is used in this scenario. If the runtime finds a NULL value, [...] Visual Basic then uses HRESULT to look up the corresponding Visual Basic error.
This explains the behavior regarding your fist example: you did supply an error message, hence the runtime simply resorts to its generic message "Method '~' of object '~' failed
" plus your HRESULT
.
The behavior of your second example is also consistent once you look at the definition of the (first listed) constructor for CComCoClass::Error
: it has defaults for the non specified parameters, especially 'hRes = 0'. The 'Remarks' section further states that "If hRes is zero, then the first four versions of Error return DISP_E_EXCEPTION.". Consequently this implicitly triggers the 'Server error' pass through behavior.
Finally, for a concrete C++ implementation sample of a VB like automation client behavior see for example paragraphs 'Error handling' and the following 'Exercise 5' in Automating Microsoft Office 97 and Microsoft Office 2000.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With