ObjectPascal
Try
Keyword
Starts code that has error trapping
1   Try
    Statement
  {Statement...}
  Finally
    Statement
  {Statement...}
  End;
2   Try
    Statement
  {Statement...}
  Except
    Statement
  {Statement...}
  End;
3   Try
    Statement
  {Statement...}
  Except
    On {Name :} Exception type Do Statement
  {Else Statement}
  End;
Description
The Try keyword is used to mark the start of a block of statements that have error trapping. If an error occurs, the program is not terminated. Instead, control is passed to either a Finally or Except section.
 
Try is used in a number of ways.
 
Version 1
 
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.
 
Version 2
 
In this version, only if the Try clause generates an exception will the Except clause be executed. This is used to take alternative action when something unexpected goes wrong. The except clause cannot determine the error type however.
 
Version 3
 
This is similar to version 2, but specifies different actions for different exception types, such as EInOutError. An Else clause can be used as a catch all for unexpected exception types. The general exception type Exception can be used to catch all exception types.
 
By assigning a Name to the exception, the message text of the exception (Name.Message) can be obtained for display or other uses.
 
When an exception is raised in a version 3 setup, if the exception is not acted upon by On or Else statements, then a check is made to see if we are in a nested Try block. If so, the Except clause of this parent Try is processed. If no On or Else clause is found, the program terminates.
 
The Else clause is not really necessary - it is better to use On E:Exception Do, the generic exception handling, since it still provides the error message (E.Message).
 
Important : you can determine the type of error that occured by using the generic exception handling - On E:Exception Do. E is a pointer to the exception object that is created by the exception condition. E.ClassName gives the exception type, such as 'EDivByZero', as shown in the final example code.
 
The following list of exceptions covers the basic types - there are hundreds of exception classes:
 
Exception Base class
EAbort Abort without dialog box
EAbstractError Abstract method error
AssertionFailed Assert call failed
EBitsError Boolean array error
ECommonCalendarError Calendar calc error
EDateTimeError   DateTime calc error
EMonthCalError   Month calc error
EConversionError   Raised by Convert
EConvertError Object convert error
EDatabaseError Database error
EExternal Hardware/Windows error
EAccessViolation   Access violation
EControlC   User abort occured
EExternalException   Other Internal error
EIntError   Integer calc error
EDivByZero     Divide by zero
EIntOverflow     Integer overflow
ERangeError     Out of value range
EMathError   Floating point error
EInvalidArgument     Bad argument value
EInvalidOp     Inappropriate operation
EOverflow     Value too large
EUnderflow     Value too small
EZeroDivide     Divide by zero
EStackOverflow   Severe Delphi problem
EHeapException Dynamic memory problem
EInvalidPointer   Bad memory pointer
EOutOfMemory   Cannot allocate memory
EInOutError IO error
EInvalidCast Object casting error
EInvalidOperation Bad component op
EMenuError Menu item error
EOSError Operating system error
EParserError Parsing error
EPrinter Printer error
EPropertyError Class property error
EPropReadOnly Invalid property access
EPropWriteOnly Invalid property access
EThread Thread error
EVariantError Variant problem
Notes
There are times when you want a construct like this :

Try
  ...
Except
  ...
Finally
  ...
End;


where exceptions are trapped and acted upon, but in all cases, a set of clean up statements are executed. This can be achieved with nested Try statements :

Try
  Try
    ...
  Except
    ...
  End;
Finally
  ...
End;

Related commands
Except Starts the error trapping clause of a Try statement
Finally Starts the unconditional code section of a Try statement
On Defines exception handling in a Try Except clause
Raise Raise an exception
 
Example code : Version 1 : Zero divide with a finally clause
var
  number, zero : Integer;
begin
  // Try to divide an integer by zero - to raise an exception
  number := -1;
  Try
    zero   := 0;
    number := 1 div zero;
    WriteLn('number / zero = '+IntToStr(number));
  finally
    if number = -1 then
    begin
      WriteLn('Number was not assigned a value - using default');
      number := 0;
    end;
  end;
end;
Show full unit code
   Number was not assigned a value - using default
  
   Then, the program terminates with an EDivByZero error message - the finally clause did not trap the error.
 
Example code : Version 2 : Zero divide with a plain Except block
var
  number, zero : Integer;
begin
  // Try to divide an integer by zero - to raise an exception
  Try
    zero   := 0;
    number := 1 div zero;
    WriteLn('number / zero = '+IntToStr(number));
  except
    WriteLn('Unknown error encountered');
  end;
end;
Show full unit code
   Unknown error encountered
 
Example code : Version 3 : Divide by zero with an Except On clause
var
  number, zero : Integer;
begin
  // Try to divide an integer by zero - to raise an exception
  Try
    zero   := 0;
    number := 1 div zero;
    WriteLn('number / zero = '+IntToStr(number));
  except
    on E : Exception do
      ShowMessage(E.ClassName+' error raised, with message : '+E.Message);
  end;
end;
Show full unit code
   EDivByZero error raised with message : Division by zero