There's something I keep running into that I really haven't solved with Delphi programs and was wondering if anyone could instruct me on it. As the topic says, how do you do proper catastrophic error handling? For instance:
// is file necessary for the program present?
if not FileExists(FilePath1) then
begin
raise Exception.Create(FilePath1 + ' does not exist and is required for this program to function.');
// I obviously need to do something here to make the program QUIT and not have
// any more code run.
Application.Terminate;
Abort;
end;
I can use the exception unit there as well and throw out an exception, but the program continues as before. I've used the halt call in the past, but it seems to not do any cleanup or the like so I end up making a big procedure with close and free calls for everything I've done just to be sure (and even then I'm not sure of any of the behind the scenes stuff).
So what is the right way to handle such things?
Edit: To clarify, I'm wanting to know about how to make the program do what clean-up it needs to do and then EXIT NOW and not do any other code.
To perform abnormal termination call Halt() passing the exit code.
if CatastropicErrorDetected then
begin
... show error message
Halt(1);
end;
On Windows this results in a call to TerminateProcess and will stop execution there and then.
You note that no cleanup is performed and usually that's what you want. Since you are performing this check at application startup there should be nothing to cleanup.
IMHO the only clean way would be checking for "Fatal conditions" before Application is running.
program Project2;
uses
Forms,Dialogs,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
ReportMemoryLeaksOnShutDown := true;
Application.Initialize;
if True then // your condition here
begin
MessageDLG('Fatal Error',mtError,[mbok],0);
end
else
begin
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
end.
Any other approach will have side effects
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private-Deklarationen }
FSL:TStringList;
public
Destructor Destroy;override;
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
destructor TForm1.Destroy;
begin
FreeAndNil(FSL);
Showmessage('Will never be seen with Application.Terminate + HALT');
inherited;
end;
procedure TForm1.FormCreate(Sender: TObject);
const
Testing=0; // try 1 and 2 too
begin
FSL:=TStringList.Create;
Try
raise Exception.Create('Terminating now');
except
case Testing of
0: begin
// exception object will not be freed other code will be prevented, Form won't be shown
Application.Terminate;
HALT;
end;
1: begin
// exception object will not be freed Form won't be shown
HALT;
end;
2: begin
// clean but Form will be shown
Application.Terminate;
end;
end;
end;
end;
end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With