DelphiBasics
  Home  |  Exception handling in your code
 Documents
 Tutorials

 Writing your first program
 Writing your second program
 Amending this program

 Delphi data types
   Numbers
   Text (strings and chars)
   Sets and enumerations
   Arrays
   Records

 Programming logic
   Looping
   SubRoutines
   Exception handling

 Dates and times

 Files

 Pointers

 Printing text and graphics

 Object Orientation basics
   Memory leaks!
   Inheritance
   Abstraction
   Interfaces
   An example class

 References

 Standard components

 Articles

 A brief history of Delphi

 Usability : file handling

 Usability : reference books

 Author links

  Exception handling in your code
Handling errors in Delphi
Whilst we all want to spend our time writing functional code, errors will and do occur in code from time to time. Sometimes, these are outside of our control, such as a low memory situation on your PC.
 
In serious code you should handle error situations so that at the very least, the user is informed about the error in your chosen way.
 
Delphi uses the event handling approach to error handling. Errors are (mostly) treated as exceptions, which cause program operation to suspend and jump to the nearest exception handler. If you don't have one, this will be the Delphi default handler - it will report the error and terminate your program.
 
Often, you will want to handle the error, and continue with your program. For example, you may be trying to display a picture on a page, but cannot find it. So you might display a placeholder instead. Much like Internet Explorer does.
 

Try, except where there are problems
Delphi provides a simply construct for wrapping code with exception handling. When an exception occurs in the wrapped code (or anything it calls), the code will jump to the exception handling part of the wrapping code :
 
 begin
   Try
     ...
     The code we want to execute
     ...
   Except
     ...
     This code gets executed if an exception occurs in the above block
     ...
   end;
 end;

We literally try to execute some code, which will run except when an error (exception) occurs. Then the except code will take over.
 
Let us look at a simple example where we intentionally divide a number by zero :
 
 var
   number1, number0 : Integer;
 begin
   try
     number0 := 0;
     number1 := 1;
     number1 := number1 div number0;
     ShowMessage('1 / 0 = '+IntToStr(number1));
   except
     on E : Exception do
     begin
       ShowMessage('Exception class name = '+E.ClassName);
       ShowMessage('Exception message = '+E.Message);
     end;
   end;
 end;

When the division fails, the code jumps to the except block. The first ShowMessage statement therefore does not get executed.
 
In our exception block, we can simpl place code to act regardless of the type of error. Or we can do different things depending on the error. Here, we use the On function to act on the exception type.
 
The On clause checks against one of a number of Exception classes. The top dog is the Exception class, parent of all exception classes. This is guaranteed to be activated above. We can pick out of this class the name of the actual exception class name (EDivByZero) and the message (divide by zero).
 
We could have multiple On clauses for specific errors :
 
   except
    // IO error
     On E : EInOutError do
       ShowMessage('IO error : '+E.Message);
    // Dibision by zero
     On E : EDivByZero do
       ShowMessage('Div by zero error : '+E.Message);
    // Catch other errors
     Else
       ShowMessage('Unknown error');
   end;


What happens when debugging
Note that when you are debugging your code within Delphi, Delphi will trap exceptions even if you have exception handling. You must then click OK on the error dialogue, then hit F9 or the green arrow to continue to your except clause. You can avoid this by changing the debug options.
 

And finally ...
Suppose that instead of trapping the error where it occurs, you may want to let a higher level exception handler in your code to do a more global trapping. But your code may have created objects or allocated memory that is now no longer referenced. It is dangerous to leave these allocations lying around.
 
Delphi provides an alternative part to the exception wrapper the Finally clause. Instead of being called when an exception occurs, the finally clause is always called after part or all of the try clause is executed. It allows us to free up allocated memory, or other such activities. However, it does not trap the error - the next highest exception handling (try) block that we are nested in is located and executed.
 
Once you are done debugging the software it is time to relax. Get up out of your modern office furniture and take a nap or go outside. It is important to take breaks from your work and have fun.
 

Raising exceptions
We can not only raise exceptions at our own choosing, but we can create Exception classes to manage them. This kind of processing is somewhat beyond the basics, being more appropriate to large applications, especially those using many large modules. These modules may generate their own exception types. Here are the most common exception types :
 
 Exception             Base class
 EAbort                Abort without dialog
 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          Integer 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         Floating 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

 
 

Delphi Basics © Neil Moffatt All rights reserved.  |  Home Page