Proper catastrophic error handling

There, I continue to encounter something that I really have not decided on with Delphi programs, and I was wondering if anyone could teach me this. As the topic says, how do you deal with the correct 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 also use the exception block and throw an exception, but the program still continues. I have used this call in the past, but it does not seem to perform any cleaning, etc., so I am doing a great procedure with closed and free calls to everything that I did to be sure (and even then I am not sure in none of the headings).

So, how to deal with such things?

Edit: To clarify, I want to learn how to make a program, clean it up, and then QUIT NOW and not make any other code.

+4
source share
4 answers

To complete the abnormal termination of the call, Halt () passes an exit code.

 if CatastropicErrorDetected then begin ... show error message Halt(1); end; 

On Windows, this will result in a TerminateProcess call and stop execution there and then.

You note that cleaning is not performed and usually this is what you want. Since you perform this check at application startup, there should be nothing to clean.

+6
source

IMHO, the only clean way would be to check the "Fatal conditions" before running the application.

 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. 
+2
source

You can tell the global application object to terminate the program by calling Application.Terminate .

End call to end the program. Call Terminate, and do not release the application object, you allow closing the application in an orderly manner .

End a call to the Windows PostQuitMessage function to perform an orderly shutdown of the application . Completion does not occur immediately.

Since the call can go deeper on the stack, you can also raise an exception , and you code your program so that it doesn't run in the order that the execution reaches the main loop of the application and the exception handler catches it by default.

This way you effectively prevent more code from running in your application.

In code, it might look like this:

 if not FileExists(FilePath1) then begin MessageDlg(FilePath1 + ' does not exist and is required for this program to function.', mtWarning, [mbOK], 0); Application.Terminate; Abort; //raising a EAbort just as an example end; 

Depending on where this code is called, I advise you not to show the message directly, but rather to raise an exception with the message and let the default HandleException method of the application object show the message for you:

 if not FileExists(FilePath1) then begin Application.Terminate; raise EMyFatalException.Create(FilePath1 + ' does not exist and is required for this program to function.'); end; 

Which looks more natural to me. EMyFatalException is a hypothetical exception class that you can declare and not handle in your except clauses.

+1
source

You can write your own Application.OnException handler, for example:

 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private procedure HandleException(Sender: TObject; E: Exception); end; var Form1: TForm1; type EMyFatalError = class(Exception); implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin Application.OnException:= HandleException; raise EMyFatalError.Create('OOPS!'); end; procedure TForm1.HandleException(Sender: TObject; E: Exception); begin Application.ShowException(E); if E is EMyFatalError then Application.Terminate; end; end. 
+1
source

All Articles