gpt4 book ai didi

delphi - 如何捕获 TDataModule.OnCreate 事件中的异常?

转载 作者:行者123 更新时间:2023-12-03 14:36:18 24 4
gpt4 key购买 nike

我在 Delphi 中使用 try/except block 遇到了以下问题。

我有一个简单的应用程序 - 一个名为 fr_MAIN 的 MainForm 和一个名为 DMTDataModuleDM 不是自动创建的,而是在运行时在 fr_MAINButton2.OnClick 事件中创建的:

procedure Tfr_MAIN.Button2Click(Sender: TObject);
begin
try
DM := TDM.Create(nil);
Showmessage('DM started!');
except
on E:Exception do
begin
Showmessage('DM not started!');
end;
end;

DM 在其 OnCreate 事件中有一些代码:

procedure TDM.DataModuleCreate(Sender: TObject);
begin
raise Exception.Create('this is error!');
// DM code here ...
end;

问题是,当我点击Button2时,我收到“这是错误!”异常消息,其余的DM代码在这里 不运行 - 这是正确的!但随后我还收到 'DM started!' 消息,而不是 'DM not started!' 消息。

DM 引发的异常会中断操作,但不会在表单的 except block 中捕获!

这是为什么?

最佳答案

TDataModule1OnCreate 事件中引发的异常进行特殊处理。

异常处理在这里:

procedure TDataModule.DoCreate;
begin
if Assigned(FOnCreate) then
try
FOnCreate(Self);
except
if not HandleCreateException then // <-- here
raise;
end;
end;

function TDataModule.HandleCreateException: Boolean;
begin
if Assigned(ApplicationHandleException) then
begin
ApplicationHandleException(Self); // <-- here
Result := True;
end
else
Result := False;
end;

默认情况下,TApplicationTApplication.HandleException() 分配给 ApplicationHandleException:

constructor TApplication.Create(AOwner: TComponent);
var
...
begin
inherited Create(AOwner);
...
if not Assigned(System.Classes.ApplicationHandleException) then
System.Classes.ApplicationHandleException := HandleException; // <-- here
if not Assigned(System.Classes.ApplicationShowException) then
System.Classes.ApplicationShowException := ShowException;
...
end;

因此,TDataModule.DoCreate() 捕获异常并将其传递给 TApplication.HandleException(),然后默认显示一个弹出对话框。由于 TDataModule.HandleCreateException() 返回 True,因此不会重新引发捕获的异常。该异常现在被视为已处理,允许程序正常继续其 Showmessage('DM started!'); 调用。

为了避免引发异常时弹出对话框,您可以分配一个 TApplication.OnException 事件处理程序:

Vcl.Forms.TApplication.OnException

Use OnException to change the default behavior that occurs when an exception is not handled by application code. The OnException event handler is called automatically in the HandleException method.

但是异常仍然会被 TDataModule.DoCreate() 捕获并消除。如果您想避免这种情况,让异常沿着调用堆栈向上传播,则根本不要从 TDataModule.OnCreate 事件引发异常。重写虚拟 TDataModule.Create() 构造函数并从那里引发异常。

1:同样的事情也发生在 TCustomForm 中。

关于delphi - 如何捕获 TDataModule.OnCreate 事件中的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47043719/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com