0

我想记录在 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 块中捕获它?

4

2 回答 2

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是你处理未处理异常的最后机会。这不是第一次有机会回应任何例外情况。

在异常发生的那一刻,在任何应用程序代码有机会做出反应或处理它们之前拦截异常可能的,但这是非常先进的东西,并且没有提供“开箱即用”的简单机制。

幸运的是,您可以使用 3rd 方库,这些库可以提供您想要引入应用程序的功能。

您可能希望查看的一个流行的 Delphi 是madExcept

于 2017-02-01T20:39:01.540 回答
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 中处理它。我避免使用一些 3rd 方框架来进行这个简单的日志记录。

于 2017-02-02T11:47:16.957 回答