我想记录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.
这非常有效,但是我没有抓住这个解决方案,在try-except块中捕获异常。
当在except块中捕获异常时,它不会触发Application.OnException事件。
有没有办法先在Application.OnException事件而不是except块中捕获它?
答案 0 :(得分:6)
仅为未处理的例外调用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;
在这种情况下,会捕获异常,但应用程序没有处理异常的策略,因此只需记录已发生的异常,然后重新引发异常。执行将在任何外部except
块中继续。如果没有,或者任何可能存在的也重新引发异常,那么最终异常将到达Application.OnException
处理程序。
但是异常处理程序可能不需要重新引发异常:
try
a := 42 / 0;
except
on EDivisionByZero do
a := 0;
end;
在这种情况下,异常处理程序处理除以零,并且不会重新提升它,因为在这种情况下代码很乐意继续结果为零(不太可能,但这只是一个例子)。
由于异常没有重新引发,执行继续进行(在try..except
块之后),好像异常从未发生过。您的Application.OnException
永远不会知道它。
总结:Application.OnException
是最后一次机会来处理未处理的异常。回复任何例外不是第一次机会。
在任何应用程序代码有机会作出反应或处理它们之前,在它们发生时拦截异常是是可能的,但它是非常先进的东西,没有提供简单的机制“方框“。
幸运的是,您可以使用第三方库,这些库可能会提供您要在应用程序中引入的功能。
A popular one for Delphi which you might wish to check out is madExcept
答案 1 :(得分:0)
我最终使用JCL来捕获和记录我的所有异常。我使用以下代码创建了一个新的.pas文件:
/// <summary>
/// Inicializa JCL para capturar la informacion necesaria de la excepcion.
/// </summary>
initialization
JclAddExceptNotifier(SetExceptionError);
JclStackTrackingOptions := JclStackTrackingOptions + [stExceptFrame];
JclStartExceptionTracking;
/// <summary>
/// Finaliza la notificacion de JCL luego de capturar la informacion necesaria de la excepcion.
/// </summary>
finalization
JclRemoveExceptNotifier(SetExceptionError);
end.
使用此代码,我可以捕获异常并在我的函数SetExceptionError中处理它。我避免使用一些第三方框架进行这种简单的日志记录。