Delphi exception handling
Introduction
Delphi has an advanced exception handling system.
In this paper we look at it and see how it can be implemented in your application.
Exception handling in Delphi
The benefit of an exception handling system as used in Delphi is that applications
can, despite of a
run time error, keep running without crashing.
The application can close normally and data can be saved.
Delphi generates an exception when a runtime error occurs.
This exception can be solved in the code. (You have to program that yourself of
course)
When the code does nothing the error 'floats' up to the calling code.
This goes on and on until there is no code anymore, at that time Delphi will try to solve
the problem.
The system
The next keywords belong to the exception handling system :
try
except
finally
raise
try is the beginning of the protected code.
except is the end of this code
finally is code that must be executed, even if an error occurs.
raise give you the possibility to generate an exception manually.
The keywords can be used in two blocks :
function DoDivide (x,y : integer) : Double;
begin
try
Result : x / y;
except //Except block
on EZeroDivide do //solve the problem
begin
Result := 0,0;
ShowMessage('Divide by zero!');
end;
end;
end;
|
The try... finally block :
try
// the code
finally
//Execute this code whatever happens!
end;
This block guaranties that the code after finally will be executed even
if a runtime error shows up.
This block is important for resource protection. For example for freeing of objects, like
a form.
The next code shows a form which is dynamically created in a Try..finally block.
procedure TForm1.button1Click(Sender : TObject);
begin
frmShowResult := TfrmShowResult.Create(self);
try //Finally block
frmShowResult.ShowModal;
Finally
frmShowResult.free;//Free the form
end;
end;
|
Raise exceptions
Raise can be used to re-raise an exception. The exception can be handled evenly.
You can also use raise to generate exceptions manually : raise
EDiveByZero.Create ('Divide by zero');
Both blocks nested together
Both blocks can be nested with each other.
Next code is a procedure which extract two numbers from each other. (Like 8 - 6)
The result may not be less then zero, if it is less then zero the outcome is zero.
The cursor is changed to a type hourglass so an finally block is also necessary.
In the except block we will nest a finally block.
Notice the use of object E. With that object, of type exception, we can handle all the
errors that might occur.
Object E receives the value of the created exception object.
Even if there are letters in the edit-boxes the appropriate message will be showed to the
user.
function TForm1.DoCalculation : Integer;
begin
Try //Finally block
Try //Except block
result := StrToInt(Edit1.text) - StrToInt(Edit2.text);
if result < 0 then //raise
raise exception.Create('Result less then zero');
except
on E:exception do //E is object of type exception
begin
result := 0;
showmessage(E.Message);
end;
end;
Finally
Screen.Cursor := crDefault; //what ever happens 'reset' the cursor
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Screen.Cursor := crHourGlass;
lblOutCome.caption := IntToStr(DoCalculation);
end;
|
Creating own exceptions
It is very easy to create your own exceptions :
type
EMyError = class ( Exception );
raise EMyError.Create ('Sorry my error!'):
End of exceptions.