2

I'm using the code below to try to create a custom error message for logging by EL. The code works for logging myself (ie when {ifNdef EUREKALOG}) - in which case the '(Extra Info)' shows in the ShowMessage, but not when calling EL logging. In the latter case, the orginal e.message is logged. Is there a way to achieve this?

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;
Freddie Bell
  • 2,186
  • 24
  • 43
  • 2
    I bet exceptions are _collected_ by the exception manager as soon as they are raised and it's too late to modify the exception message like you do. Why do you want to do that, anyway? Raise that exception with the extra info and you're done. – Victoria Jun 23 '17 at 12:46
  • Excellent answer. if I (re-)raise the exception with `raise exception.create(e.message)` instead of `EBASE...`, Eurekalog traps the new exception as expected. If you actually answer the question, with corrected code, I'll mark it as the answer. – Freddie Bell Jun 23 '17 at 13:20
  • So you know that extra info only inside that exception handler? Re-raising will create two exception entries in log. I was thinking about raising the original exception with that extra info. – Victoria Jun 23 '17 at 15:41
  • Actually not Victoria. The on e: exception traps the first exception without involving EL. The (re-) raise actually does raise a new exception with the altered e.message which IS trapped by EL. That's why your answer is GOOD (at least on Delphi 10.x it is) – Freddie Bell Jun 23 '17 at 16:17
  • @Victoria I have answered my own question below so you can see how this works. – Freddie Bell Jun 23 '17 at 16:22
  • 1
    Yeah, then you'll get two exceptions logged. Maybe [LastThreadException](https://www.eurekalog.com/help/eurekalog/index.php?topic_property_eexceptionmanager_texceptionmanager_lastthreadexception.php) allows you to modify the logged exception object, but I'm not sure about it. I guess it remains logged as was raised and caught by the hook. Modifying [ExceptionMessage](https://www.eurekalog.com/help/eurekalog/index.php?topic_property_eexception_teurekaexceptioninfo_exceptionmessage.php) might be the way to go. – Victoria Jun 23 '17 at 16:42

2 Answers2

2

The previous answers are correct: EurekaLog captures exception's information when exception is raised. It does not know that you have changed exception object later. You need to explicitly tell EurekaLog new information. For example:

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;
Alex
  • 5,477
  • 2
  • 36
  • 56
1
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;
Freddie Bell
  • 2,186
  • 24
  • 43
  • You don't need to use `AcquireExceptionObject` to modify an exception. You already have access to it from the `on` statement. `e` is just an object in memory, like any other. You don't need to use `on e: Exception` and `AcquireExceptionObject` together: `on 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;` – Remy Lebeau Jun 23 '17 at 20:33
  • 2
    As for raising a new exception, using `raise Exception.Create(e.Message);` loses all type and address details of the original exception. You could just re-raise the modified exception: `on e: Exception do begin e.Message := e.Message + '(Extra info) '; raise; end;` Or, consider using `Exception.RaiseOuterException()` instead, which captures the existing exception in the `InnerException` property of the new exception: `on e: Exception do begin Exception.RaiseOuterException(Exception.Create('Something happened! Check InnerException for details')); end;` – Remy Lebeau Jun 23 '17 at 20:34
  • 1
    @Remy, true, although, this question is about modifying what is logged by EurekaLog (why else would someone like to modify exception object). And since EurekaLog uses hooks to catch exceptions, it is too late to modify something from the exception handler. It is already logged. – Victoria Jun 24 '17 at 15:57