|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 :
The code we want to execute
This code gets executed if an exception occurs in the above block
|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 :
number1, number0 : Integer;
number0 := 0;
number1 := 1;
number1 := number1 div number0;
ShowMessage('1 / 0 = '+IntToStr(number1));
on E : Exception do
ShowMessage('Exception class name = '+E.ClassName);
ShowMessage('Exception message = '+E.Message);
|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 :
// 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
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.
|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