• support@ifer.cz
  • +420 2 4195 0607

Handling exceptions – Try..Except..Finally

By Martin Cerny / Oct 16, 2016

In course of Field-Map Pascal script execution various errors may appear. Such numerical, file or other errors raise exceptions which breaks script execution. Exceptions can be handled by Field-Map Pascal script in order to keep script execution under full control.
For handling exception the try..except and try..finally constructs are available.
In a Try..Finally construct, the Finally statement is guaranteed to be executed absolutely regardless of what happens in the try clause. However, the Finally clause does not actually handle any exceptions – the program will terminate if no Except clause is found (see notes below).
Try..Finally is normally used by a routine to allow cleanup processing to take place, such as freeing resources, with the exception being correctly passed to the caller to handle.

var q :TTableWrapper;
begin
  q := Project.GetQueryResult('SELECT ID FROM Plots');
  try
    … here work with query result …
  finally
    q.Free; //free query from memory
  end;
end.


In this particular case the query is being created, used and freed from memory. Query is removed from memory in any case even if the Exit command is used within try..finally construct.
Try..Except is used to trap and handle exceptions in the program. Whenever the error occurs between Try and Except clause the program goes to Except part and continues without stopping program execution.

var
  number, zero : Integer;
begin
  // Try to divide an integer by zero – to raise an exception
  try
    zero   := 0;
    number := 1 div zero;
    ShowMessage('number / zero = '+IntToStr(number));
  except
    ShowMessage('Unknown error encountered');
  end;
end.


Number was not assigned. Then, the program raises EDivByZero exception – the except clause traps the error and shows user defined message.
For more sophisticated work with exceptions there are several additional methods:

procedure RaiseException(Ex :TIFException; Param :String);
procedure RaiseLastException;
function ExceptionParam :string;
function ExceptionPos :cardinal;
function ExceptionProc :cardinal;
function ExceptionToString(er : TIFException; Param :string) :string;
function ExceptionType : TIFException;

Exception may be of various types:

TIFException = (ErNoError, erCannotImport, erInvalidType, ErInternalError, erInvalidHeader, erInvalidOpcode, erInvalidOpcodeParameter, erNoMainProc, erOutOfGlobalVarsRange, erOutOfProcRange, ErOutOfRange, erOutOfStackRange, ErTypeMismatch, erUnexpectedEof, erVersionError, ErDivideByZero, ErMathError,erCouldNotCallProc, erOutofRecordRange, erOutOfMemory, erException, erNullPointerException, erNullVariantError, erInterfaceNotSupported, erCustomError)

With the use of available methods it is for instance possible to work with more detailed information about exception which has happened:

var
  number, zero : Integer;
begin
  // Try to divide an integer by zero – to raise an exception
  try
    zero   := 0;
    number := 1 div zero;
    ShowMessage('number / zero = '+IntToStr(number));
  except
    ShowMessage(ExceptionParam+' encountered');
  end;
end.

or even to raise exception by the user:

var filename :string;
begin
 
  filename := ProjectDir+'MISC\'+'MyTestFile.xml';
 
  if not FileExists(filename) then
    RaiseException(erCustomError,format('File "%s" not found.',[filename]))
    
  else begin
    //here process XML file
    
  end;

end.


Try..Except and Try..Finally construct can be combined into Try..Except..Finally:

var x,y,z :double;  
begin   
   try
    x := 10;
    z := 0;
    y := x/z;
  except
    Showmessage('leaving try..except'#13+ExceptionParam);
  finally
    Showmessage('leaving try..finally');
  end;

end.


You must be logged in to post a comment