delphi - 异常消息来自哪里?
问题描述
EZeroDivide
当出现, EOverflow
, ...之类的异常时EMathError
,它们会出现一条默认消息。
例如,以下代码引发EZeroDivide
带有以下消息的 an:
浮点除以零
procedure TForm1.Button1Click(Sender: TObject);
var
N : Extended;
D : Extended;
begin
N := 100;
D := 0;
Caption := FloatToStr(N/D);
end;
当我通过代码“手动”引发EZeroDivide
异常时,我必须将Msg
参数传递给构造函数,并将其作为EZeroDivide
具有空字符串消息的异常引发:
procedure TForm1.Button2Click(Sender: TObject);
begin
raise EZeroDivide.Create('');
end;
默认异常消息来自哪里?
解决方案
这些异常实例由 RTL 在内部生成。问题中的具体字符串可以在resourcestring
SysConst.pas 部分找到
SZeroDivide = 'Floating point division by zero';
RTL 在内部使用该Error
方法引发此类异常。运行时错误的完整列表System
在以下枚举的单元中定义:
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
);
如果您有真正的理由自己引发运行时错误,您可以通过调用来做到这一点,例如:
System.Error(reZeroDivide);
如果您非常细心,您会注意到该单元Error
中没有前向声明,System
而仅存在于实现部分中。通常,这会阻止您在其包含单元之外调用该方法,但该System
单元在许多方面都是特殊的,并且此方法可以全局访问。请注意,您通常还会包含该Windows
单元,并且这声明了一个名为的 const ERROR
,它通常会隐藏System.Error
,因此通常需要明确地确定它的范围。
推荐阅读
- powershell - 全局停止作业:作业未定义为 ID 或值
- javascript - Javascript(Typescript)错误处理 - 将父错误类转换为子类
- javascript - 如何使用 React HashRouter 和 Apollo 客户端渲染反应类组件?
- shopify - 为什么所有主题都在更新?shopify 主题套件
- c# - 类属性的 TypeConverter 用法
- c++ - Apache ORC 在读取数据时跳过条纹
- groovy - In Groovy - How to add comma in git tag list?
- bash - 如何使用 BASH 脚本使用参数“国家”或“首都”仅打印要筛选的国家或首都
- android - 如何在 Jetpack 组合中使用 Viewmodel
- angular - 如何从网页上的日历中获取链接以将其导出到谷歌日历?