Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

AW: SystemException Ursache finden

  Alt 14. Apr 2020, 12:23
Es gibt Erweiterungen, welche auch im Programm einen Stacktrace bei Fehlermeldungen anzeigen.
z.B. Eurekalog, MadExcept oder jclDebug/jclHookExceptions (JEDI)

pssst:
Format('Name der Sequenz', [E.Message]) > das fehlende %s ist bestimmt nur ein Fehler beim Kopieren,
aber Format? > raise Exception.CreateFmt('Name der Sequenz: %s', [E.Message]);

Per se ist es eigentlich schöner die originale Exception beizubehalten, denn so manche Exception-Klasse hat Zusatzinfos, die sonst verloren gehen.
Delphi-Quellcode:
except
  on E: Exception do begin
    E.Message := 'Name der Sequenz: ' + E.Message;
    raise;
  end;
end;
Aber gerade bei System-Exception hat Delphi ein echt saublödes Verhalten, denn beim Re-Raise kann es passieren (z.B. wenn die Exception durch die Messagebehandlung von Windows rauscht),
dass Delphi die originale Windows-Exception wiederherstellt und dabei der geänderte Text flöten geht.

Hier könnte man nun mit verschachtelten Inner-Exceptions arbeiten,
Delphi-Quellcode:
// TApplicationEvents.OnException
procedure TForm1.ApplicationEvents1Exception(Sender: TObject; E: Exception);
var
  S: string;
begin
  while Assigned(E) do begin
    if S <> 'then
      S := S + sLineBreak + sLineBreak;
    S := S + E.ClassName + ': ' + sLineBreak + Trim(E.Message);
    E := E.InnerException;
  end;
  ShowMessage(S);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  try
    Tag := Tag div Tag; // Division durch 0
  except
    Exception.RaiseOuterException(Exception.Create('Name der Sequenz'));
  end;
end;
Code:
Exception:
Name der Sequenz

EDivByZero:
Division durch Null
Delphi-Quellcode:
// falls man etwas hat, dass sich bei Exception.GetStackInfoStringProc registriert hat und den Stacktrace liefert
procedure TForm1.ApplicationEvents1Exception(Sender: TObject; E: Exception);
var
  S, T: string;
begin
  //T := E.StackTrace; // Stack der äußeren Exception, aber uns interessiert ja die Innersten/Ursprünglichen viel mehr
  while Assigned(E) do begin
    if S <> 'then
      S := S + sLineBreak + sLineBreak;
    S := E.ClassName + ': ' + sLineBreak + Trim(E.Message);
    if not (E.InnerException) and Assigned(E.StackInfo) then
      S := S + sLineBreak + sLineBreak + 'Stacktrace:' + sLineBreak + E.StackTrace;
    E := E.InnerException;
  end;
  //if T <> '' then
  // S := S + sLineBreak + sLineBreak + 'Stacktrace:' + sLineBreak + T;
  ShowMessage(S);
end;
aber der hauseigene Fehlerdialog von Delphi ist ein bissl "dämlich" und Zeigt sowas nicht an.
$2B or not $2B
  Mit Zitat antworten Zitat