Search code examples
delphiexceptiondelphi-2007exit-codehalt

How to return an error code with Halt(n) from an Exception block with D2007?


Update: It seems to be specific to D2007. It works in D2010 like it worked in older version.

I would like to return an exit code depending on the type of Exception caught in the Eception Handler block like:

program test;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  Exitcode: Integer;
begin
  Writeln('Enter error code:');
  Readln(Exitcode);
  try
    raise EExternal.Create('sdsdkfjh');
  except
    on E:EExternal do
    begin
      Writeln(E.Classname, ': ', E.Message);
      Halt(Exitcode);
    end;
  end;
end.

Unfortunately in D2007, calling Halt(n) from an Exception block always returns an Exit code 1, no matter what you pass to Halt().

Apparently because exiting from an Exception handler calls Finalize, which clears the pending (non Abort) Exceptions, calling SysUtils.ExceptHandler:

procedure ExceptHandler(ExceptObject: TObject; ExceptAddr: Pointer); far;
begin
  ShowException(ExceptObject, ExceptAddr);
  Halt(1); // <= @#$##@#$!
end;

And no matter what exit code I wanted I get that Halt(1)!

So the question is:
How can I simply return the desired Exit code depending on which Exception was raised?


Solution

  • Will this work?

    NeedHalt := False;
    try
      raise EExternal.Create('sdsdkfjh');
    except
      on E:EExternal do
      begin
        Writeln(E.Classname, ': ', E.Message);
        NeedHalt := True;
      end;
    end;
    if NeedHalt then
      Halt(Exitcode); 
    

    Or this?

    try
      raise EExternal.Create('sdsdkfjh');
    except
      on E:EExternal do
      begin
        Writeln(E.Classname, ': ', E.Message);
        AcquireExceptionObject;
        Halt(Exitcode); 
      end;
    end;
    

    Anyway: it's a bug in D2007, which was fixed in D2010.