When an interface returns a delegated object that causes an error, the factory or autofactory has not been assigned.
The default implementation of SafeCallException refers to FFactory which, in this case is NIL. Override SafeCallException to fix. In COMOBJ.pas, the SafeCallException procedure refers to FFactory.ErrorID, FFactory.ProgID, etc in the call to HandleSafeCallException. FFactory is nil, causing a AV in the error handler, which causes a Catastrophic Error to be raise.
If you descend your objects from a TFudgedAutoObject which simply overrides the SafeCallException message, you can solve the problem.
function TFudgedAutoObject.SafeCallException(ExceptObject: TObject;ExceptAddr: Pointer): HRESULT;
var
E: TObject;
CreateError: ICreateErrorInfo;
ErrorInfo: IErrorInfo;
begin
Result := E_UNEXPECTED;
E := ExceptObject;
if Succeeded(CreateErrorInfo(CreateError)) then
begin
CreateError.SetGUID(Class_EPO);
CreateError.SetSource(PWideChar(‘MY ERROR SOURCE’));
CreateError.SetHelpFile(PWideChar(‘MY HELPFILE NAME.HLP’));
if E is Exception then
begin
CreateError.SetDescription(PWideChar(WideString(Exception(E).Message)));
CreateError.SetHelpContext(Exception(E).HelpContext);
if (E is EOleSysError) and (EOleSysError(E).ErrorCode < 0) then
Result := EOleSysError(E).ErrorCode;
end;
if CreateError.QueryInterface(IErrorInfo, ErrorInfo) = S_OK then
SetErrorInfo(0, ErrorInfo);
end;
end;
Comments
Very cool tip!
Written by Guest on 2005-06-08 15:53:46
I’ve been stuck on this problem for a bit. Hopefully this will fix it. Thank you!
In D7 I had to
1. Add ActiveX to my uses clause
2. Define a string constant GUID like this
const
MYGUID = ‘{678077B3-095F-4ECE-836D-7E1172C20979}’;
3. Change the call to SetGUID to
CreateError.SetGUID(StringToGUID(MYGUID));
4. Change the calls to SetSource and SetHelpFile to
CreateError.SetSource(StringToOleStr(‘MY ERROR SOURCE’));
Written by lummie on 2005-06-09 11:19:00
Ah yes I left my application GUID in SetGUID.
Customize it to your application as above. Thanks Guest
One reply on “Resolving “Catastrophic Failure” in COM”
Finally a solution to the incrediably annoying Access Violations seen inside the debugger.
I’d really like to know why Delphi hasn’t updated their ComObj unit to include this fix, as it seems like a major bug on their end.
Thanks.