And*_*res 0 delphi try-catch onexception
我想记录delphi应用程序中引发的每个异常.为此,我在项目源代码中用我自己的一个覆盖了Application.OnException事件.
program Project;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1},
Logger in 'Logger.pas',
JCLDebugHandler in 'JCLDebugHandler.pas';
{$R *.res}
begin
Application.Initialize;
Application.OnException := TApplicationException.AppException;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Run Code Online (Sandbox Code Playgroud)
这很好用,但我没有抓住这个解决方案,在try-except块中捕获了异常.
当在except块中捕获异常时,它不会触发Application.OnException事件.
有没有办法首先在Application.OnException事件而不是except块中捕获它?
该Application.OnException处理器只要求未处理的异常.
未处理的异常是指没有try..except块已捕获异常或已捕获然后重新引发的异常.
使用一些简单的示例来演示,让我们假设这实际上是应用程序中唯一的代码,并且没有其他异常处理程序......
try
a := 42 / 0;
except
on EDivisionByZero do
begin
Log.i('Silly division by zero error has been logged');
raise;
end;
end;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,会捕获异常,但应用程序没有处理异常的策略,因此只需记录已发生的异常,然后重新引发异常.执行将在任何外部except块中继续.如果没有,或者任何可能存在的也会重新引发异常,那么最终异常将到达Application.OnException处理程序.
但是异常处理程序可能不需要重新引发异常:
try
a := 42 / 0;
except
on EDivisionByZero do
a := 0;
end;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,异常处理程序处理除以零,并且不会重新提升它,因为代码很乐意在这种情况下继续使用零结果(不太可能,但这只是一个例子).
由于不重新引发异常,因此执行继续执行(在try..except块之后),就好像异常从未发生过一样.你Application.OnException永远不会知道它.
总结: Application.OnException是你处理未处理异常的最后机会.这不是第一次回应任何例外的机会.
在任何应用程序代码有机会作出反应或处理它们之前,在它们发生时拦截异常是可能的,但这是非常先进的东西,并且没有提供"开箱即用"的简单机制.
幸运的是,您可以使用第三方库,这些库可能会提供您要在应用程序中引入的功能.