When exceptions like EZeroDivide
, EOverflow
, EMathError
... are raised, they appear with a default message.
For example, the following code raises an EZeroDivide
with the following message:
Floating point division by zero
procedure TForm1.Button1Click(Sender: TObject);
var
N : Extended;
D : Extended;
begin
N := 100;
D := 0;
Caption := FloatToStr(N/D);
end;
When I "manually" raise an EZeroDivide
exception by code, I have to pass the Msg
parameter to the constructor and it is raised as an EZeroDivide
exception which have an empty string message:
procedure TForm1.Button2Click(Sender: TObject);
begin
raise EZeroDivide.Create('');
end;
Where does default exception messages come from?
Exception messages depend on the transaction being carried out and are meant to inform you of an important or critical event (for example, start date lies in the past, safety stock has been exceeded). By means of the exception messages, you can easily sort out any materials that you need to reprocess manually.
An exception is thrown for one of three reasons: An abnormal execution condition was synchronously detected by the Java virtual machine. Such conditions arise because: evaluation of an expression violates the normal semantics of the language, such as an integer divide by zero, as summarized in §15.6.
Exceptions provide the means to separate the details of what to do when something out of the ordinary happens from the main logic of a program. In traditional programming, error detection, reporting, and handling often lead to confusing spaghetti code.
If you want the error class, error message, and stack trace, use sys. exc_info() . The function sys. exc_info() gives you details about the most recent exception.
Those exception instances are generated internally by the RTL. The specific string in the question can be found in the resourcestring
section of SysConst.pas
SZeroDivide = 'Floating point division by zero';
Internally the RTL uses the Error
method to raise such exceptions. The full list of runtime errors is defined in the System
unit in the following enum :
TRuntimeError = (reNone, reOutOfMemory, reInvalidPtr, reDivByZero,
reRangeError, reIntOverflow, reInvalidOp, reZeroDivide, reOverflow,
reUnderflow, reInvalidCast, reAccessViolation, rePrivInstruction,
reControlBreak, reStackOverflow,
{ reVar* used in Variants.pas }
reVarTypeCast, reVarInvalidOp,
reVarDispatch, reVarArrayCreate, reVarNotArray, reVarArrayBounds,
reAssertionFailed,
reExternalException, { not used here; in SysUtils }
reIntfCastError, reSafeCallError,
reMonitorNotLocked, reNoMonitorSupport
{$IF defined(LINUX) or defined(MACOS) or defined(ANDROID)}
, reQuit
{$ENDIF LINUX or MACOS or ANDROID}
{$IFDEF POSIX}
, reCodesetConversion
{$ENDIF POSIX}
, rePlatformNotImplemented, reObjectDisposed
);
If you have a genuine reason for raising a runtime error yourself you can do it by calling, for example :
System.Error(reZeroDivide);
If you're very observant, you'll notice that Error
does not have a forward declaration in the System
unit but exists only in the implementation section. Typically this would prevent you from having visibility to call the method outside of its containing unit, but the System
unit is special in many ways and this method is accessible globally. Just beware that you will also often be including the Windows
unit and this declares a const named ERROR
which will usually hide System.Error
, so scoping it explicitly is usually required.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With