Delphi has an advanced exception handling system.
In this paper we look at it and see how it can be implemented in your application.
A D V E R T I S E M E N T
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.s
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;
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.
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
EAbortAbort without dialog
EAbstractErrorAbstract method error
AssertionFailed Assert call failed
EBitsErrorBoolean array error
ECommonCalendarErrorCalendar calc error
EDateTimeErrorDateTime calc error
EMonthCalErrorMonth calc error
EConversionErrorRaised by Convert
EConvertError Object convert error
EDatabaseErrorDatabase error
EExternal Hardware/Windows error
EAccessViolationAccess violation
EControlC User abort occured
EExternalExceptionOther Internal error
EIntError Integer calc error
EDivByZeroInteger Divide by zero
EIntOverflowInteger overflow
ERangeError Out of value range
EMathErrorFloating point error
EInvalidArgumentBad argument value
EInvalidOpInappropriate operation
EOverflow Value too large
EUnderflowValue too small
EZeroDivide Floating Divide by zero
EStackOverflowSevere Delphi problem
EHeapExceptionDynamic memory problem
EInvalidPointer Bad memory pointer
EOutOfMemoryCannot allocate memory
EInOutError IO error
EInvalidCastObject casting error
EInvalidOperation Bad component op
EMenuErrorMenu item error
EOSErrorOperating system error
EParserErrorParsing error
EPrinterPrinter error
EPropertyErrorClass property error#
EPropReadOnly Invalid property access
EPropWriteOnlyInvalid property access
EThread Thread error
EVariantError Variant problem