How do I raise exceptions in a COM server to be consumed be a COM client? My server and client are written in Delphi if that makes any difference? Basically I have a background thread checking various things in my server. When it is not happy, it should stop whatever the server is doing, and raise an exception. This exception needs to be caught by the client. Not sure how to handle it though.
1 Answers
The simple answer is that you don't. Exceptions are not part of the COM interop specification and so should not cross module boundaries. You indicate errors with status codes.
Catch the exception just before your method exits (in each COM interface method). Turn the result into an error code. If you use an HRESULT
then you can consume it as safecall
and get the Delphi compiler to re-raise an exception on the other side of the fence.
The always knowledgeable Rob Kennedy points out in a comment that safecall
can be used "both sides of the fence" which makes life even easier than outlined above.
I'm not an expert on this at all (hence the need to be educated by Rob's comment). However, the documentation indicates that when you are implementing safecall
routines you should override TObject.SafeCallException
to convert exceptions into HRESULT
error codes. Some of the standard COM related classes provide overriden versions but you may need to add some of your own logic to the mix. The compiler writes implicit Try/Except blocks in safecall routines that handle exceptions by calling this virtual function.

- 601,492
- 42
- 1,072
- 1,490
-
3In fact, you can use safecall on both sides of the fence. Delphi puts an implicit try-except block inside safecall functions and translates exceptions into HResults. It also translates the declared return type into an "out" parameter and inserts an implicit HResult return type. – Rob Kennedy Apr 12 '11 at 20:24
-
@rob great I never knew that. How does it translate an exception into an HRESULT? – David Heffernan Apr 12 '11 at 20:30
-
Some explanation [here](http://stackoverflow.com/questions/96042/whats-safecall/97107#97107). – Sertac Akyuz Apr 12 '11 at 22:02
-
In a safecall function, the compiler wraps the body in a try-except block. If an exception occurs, control goes to the `_HandleAutoException` function in System.pas. If the safecall function wasn't a method, then the HResult returned is always E_Unexpected. Otherwise, it was a safecall method, so it calls SafeCallException to allow the object to perform a better exception-to-HResult translation; the default TObject implementation just returns E_Unexpected. – Rob Kennedy Apr 13 '11 at 13:24