【问题标题】:How to set e.message before Eurekalog call如何在 Eurekalog 调用之前设置 e.message
【发布时间】:2017-06-23 12:04:57
【问题描述】:

我正在使用下面的代码尝试创建自定义错误消息以供 EL 记录。该代码适用于记录自己(即当 {ifNdef EUREKALOG} 时) - 在这种情况下,“(额外信息)”显示在 ShowMessage 中,但在调用 EL 记录时不显示。在后一种情况下,会记录原始 e.message。有没有办法做到这一点?

on e: exception do
begin
  e := Exception(AcquireExceptionObject);
  e.Message := '(Extra info) ' + e.Message;
{$if defined(EUREKALOG)}
  // EExceptionManager.ExceptionManager.ShowLastExceptionData;
  // OR
  EBASE.HandleException(e);
{$else}
  ShowMessage(e.message + ' I got this, thanks!');
{$endif}
  ReleaseExceptionObject;
end;

【问题讨论】:

  • 我敢打赌,异常管理器一旦提出异常就会收集,而像您这样修改异常消息为时已晚。无论如何,你为什么要这样做?使用额外的信息引发该异常,您就完成了。
  • 优秀的答案。如果我(重新)使用raise exception.create(e.message) 而不是EBASE... 引发异常,Eurekalog 会按预期捕获新异常。如果你真的用更正的代码回答了这个问题,我会把它标记为答案。
  • 所以你只知道那个异常处理程序中的额外信息?重新引发将在日志中创建两个异常条目。我正在考虑使用这些额外信息提出原始异常。
  • 其实不是维多利亚。 on e: 异常捕获第一个异常而不涉及 EL。 (重新)引发实际上确实引发了一个新的异常,该异常是由 EL 捕获的已更改的 e.message。这就是为什么你的答案是好的(至少在 Delphi 10.x 上是这样)
  • 是的,那么您将记录两个异常。也许LastThreadException 允许您修改记录的异常对象,但我不确定。我猜它仍然被记录,因为它被提升并被钩子抓住了。修改ExceptionMessage 可能是要走的路。

标签: delphi eurekalog


【解决方案1】:

前面的答案是正确的:EurekaLog 在引发异常时捕获异常的信息。它不知道您稍后更改了异常对象。你需要明确告诉 EurekaLog 新信息。例如:

uses
  EException,        // for TEurekaExceptionInfo
  EExceptionManager; // for ExceptionManager

procedure TForm1.Button1Click(Sender: TObject);
{$IFDEF EUREKALOG}
var
  EI: TEurekaExceptionInfo;
{$ENDIF}
begin
  try
    raise Exception.Create('Error Message');
  except
    on E: Exception do
    begin
      E.Message := E.Message + sLineBreak + 'Hello from except block';

      {$IFDEF EUREKALOG}
      EI := ExceptionManager.Info(E);
      // Сould be NIL if EurekaLog is disabled or instructed to ignore this exception
      if Assigned(EI) then
        // Overrides both dialog and logs
        EI.ExceptionMessage := E.Message;
        // OR:
        // Overrides only dialogs
        // EI.AdditionalInfo := E.Message;
      {$ENDIF}

      raise; // or Application.ShowException(E);
    end;
  end;
end;

【讨论】:

    【解决方案2】:
    procedure TForm1.btnTryExceptELClick(Sender: TObject);
    begin
      try
        ProcWithError;
      except
      on e: exception do
      begin
      e := Exception(AcquireExceptionObject);
      try
        e.Message := E.Message + '(Extra info) ';
        {$if defined(EUREKALOG)}
          raise Exception.Create(e.message); // with "extra info"
        // if you really want to do this yourself (for no reason)
        //    EExceptionManager.ExceptionManager.ShowLastExceptionData;
        // OR
        //  EBASE.HandleException(e);
        {$else}
          ShowMessage(e.message + ' I''ve got this, thanks!');
          LogError(e.message);
        {$endif}
      finally
        ReleaseExceptionObject;
      end;
      end;
      end;
      ShowMessage('After except');
    end;
    

    【讨论】:

    • 您不需要使用AcquireExceptionObject 来修改异常。您已经可以通过 on 语句访问它。 e 只是内存中的一个对象,就像其他任何对象一样。你不需要同时使用on e: ExceptionAcquireExceptionObjecton e: exception do begin e.Message := '(Extra info) ' + e.Message; {$if defined(EUREKALOG)} EBASE.HandleException(e);{$else}ShowMessage(e.message + ' I got this, thanks!');{$endif} end;
    • 至于引发新异常,使用raise Exception.Create(e.Message); 会丢失原始异常的所有类型和地址详细信息。您可以重新引发修改后的异常:on e: Exception do begin e.Message := e.Message + '(Extra info) '; raise; end; 或者,考虑改用 Exception.RaiseOuterException(),它会在新异常的 InnerException 属性中捕获现有异常:on e: Exception do begin Exception.RaiseOuterException(Exception.Create('Something happened! Check InnerException for details')); end;
    • @Remy,是的,虽然,这个问题是关于修改 EurekaLog 记录的内容(为什么有人想修改异常对象)。而且由于 EurekaLog 使用钩子来捕获异常,因此从异常处理程序中修改某些内容为时已晚。它已被记录。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多