Home

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 :

The try......except block :

try
  // the code
except
  on exception do // Solve the problem
end;

When the code in the try part doesn't generate an error then the code in de except part will never be used.
If an error occurs the program will continue after except.
The error can be determined and solved.
The user will not see the by Delphi generated exception. (That one is destroyed)
So excepts allows a solution for the error and a friendly message to the user.
The next code handles an division by zero error :

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.

arrows.gif (215 bytes)Top