Question and Answer Database FAQ: FAQ4622C — OLE exceptions Category: ActiveX/OLE/COM/ActiveForm Platform: All-32Bit Product: C++Builder4.x, Question: I have a DLL containing COM objects written in VisC++ 6, which return rich error information via IErrorInfo. I have imported my type library into both C++ Builder 4 and Delphi 4, and have found an inconsistency. In Delphi, i deliberately call a method of one of my COM objects with arguments which will force an error. Delphi succesfully catches this exception in a catch block as an EOleException, ie: var myObj : IMyObject; begin try myObj := CoMyObject.Create; myObj.Load(1,1,1); // this will return E_FAIL and some rich error information except on e : EOleException do MessageDlg(e.Message,mtWarning,[mbOk],0); // message displays ok end; end; .. however I do the equivalent in C++ Builder4, and the exception is never thrown. CB4 simply returns an HRCHECK failed message, but then carries on executing ie: CoMyObject oMyObject; TCOMIMyObject pIMyObject = oMyObject.Create(); try { pIMyObject->Load(1,1,1); } catch(EOleException *e) { ShowMessage(e->Message); } Why does is the exception not thrown is C++ Builder????? Answer: Server Support for Rich Error Information =============================== ATL exposes overloaded versions of Error(...) that provide the support on the server side. And we already generate code that uses that support. The typical C++Builder Server implementation method looks as follows: STDMETHODIMP TCoClassNameImpl::MethodName(...) { try { // Do something here } catch(Exception &e) { // << This sets Rich Error Information — see ComCoClass<>::Error() return Error(e.Message.c_str(), IID_ICoClassName); } return S_OK; } We expect Server builders to enhance the call to Error(..) to use the full functionality exposed by the various/overload ATL's ComCoClass<>::Error() methods. The wizard cannot fill in the additional information but the programmer of the Server simply needs to tweak the Error(..) call to pass additional information to the client. [NOTE: Comobj::HandleSafeCallException provides similar support in a more VCL-ish way] Client Support for Rich Error Information =============================== Client side support is harder to access: System.hpp exposes a pointer, SafeCallErrorProc, that maps to Comobj's SafeCallError(). The latter handles the Client side of retrieving the IErrorInfo, loading an EOleException instance with the error information, and raising an exception. We *don't* expect Client builders to access 'SafeCallErrorProc' because System.hpp exposes it as an opaque pointer. In Delphi this function is invoked behind the scene by the code generated by the compiler when one invokes a SafeCall method. In C++ we would wrap calls to __stdcall methods to jump to SafeCallErrorProc automatically if the call fails. 8/4/99 11:49:28 AM
Last Modified: 01-SEP-99