Categories
Delphi

Resolving “Catastrophic Failure” in COM

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.

Comments are closed.