Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

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

Exception-Behandlung weiterreichen

  Alt 5. Sep 2009, 23:19
Also, da ich ja nun mein himXML nochmal in großen Teilen grundlegend überarbeite, bin ich nun auch an der Exception-Behandlung dran ...

Mein Problem ist nun das Abfangen externer Exceptions, welche mit meinen Programmteilen selber nix zu tun haben. Worauf ich auch absolut keinen Einfluß hab, welches aber dein eigenen Programmablauf eigenlich nicht stören soll.

Die eigenen Exceptions werden ja notfalls behandelt und meißtens mit Abruch meiner Rutienen nach außen weitergegeben.

Nun soll aber bei den erwähnten Exceptions nichts abbrechen, aber es soll dennoch der Mechianismuß ausgelößt werden, wie wenn eine Exception bis zur "Basis" durchwandert.

In den altuell gestellten Sourcens sieht es ja noch so aus:
Delphi-Quellcode:
Procedure TXMLFile.DoNodeChange(Node: TXMLNode; CType: TXMLNodeChangeType);
  Begin
    _Changed := True;
    If Assigned(_OnNodeChange) Then
      Try
        _OnNodeChange(Node, CType);
      Except
        ShowException(ExceptObject, ExceptAddr);
      End;
  End;
Da nun aber die Verwendung von ExceptObject und ExceptAddr, bei eventuell vorhandenen MultiThread-Anwendungen, im Grunde ganz böse sein seins sollen, hatte ich es kurzzeitig so.
Delphi-Quellcode:
Procedure TXMLFile.DoNodeChange(Node: TXMLNode; CType: TXMLNodeChangeType);
  Begin
    _Changed := True;
    If Assigned(_OnNodeChange) Then
      Try
        _OnNodeChange(Node, CType);
      Except
        On E: Exception do ShowException(E, nil);
      End;
  End;
Aber nun ist ShowMessage ja auch nicht das Wahre,
denn was ist, wenn jemand global die Exceptions nicht anzeigt, sondern z.B. mitloggt?

OK, nun ging der Weg also da hin:
Delphi-Quellcode:
Procedure TXMLFile.DoNodeChange(Node: TXMLNode; CType: TXMLNodeChangeType);
  Begin
    _Changed := True;
    If Assigned(_OnNodeChange) Then
      Try
        _OnNodeChange(Node, CType);
      Except
        If Assigned(ApplicationHandleException) Then
          {Classes.}ApplicationHandleException(E)
        Else If Assigned(ApplicationShowException) Then
          {Classes.}ApplicationShowException(E)
        Else
          {SysUtils.}ShowException(E, nil);
      End;
  End;
Dieses sieht ja nun erstmal garnicht soooo schlecht aus, aber nur wenn man nicht genauer hinguckt.

Also beim eintreten einer Exception wird z.B. ApplicationHandleException aufgerufen, dort meldet sich z.B. TApplication an und hat da {T}Application.HandleException angemeldet, welches wiederum {T}Application.OnHandleException aufruft, wo man ja wiederrum was Eigenes eintragen kann.

Aber beim genauen Hingucken, da mich dieses Sender etwas störte/irritierte,
Delphi-Quellcode:
var
  ApplicationHandleException: procedure (Sender: TObject) of object = nil;
stieß ich doch wieder auf dieses "böse" ExceptObject
Delphi-Quellcode:
procedure TApplication.HandleException(Sender: TObject);
var
  O: TObject;
begin
  if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
  O := ExceptObject;
Ja und nun meine Frage, wie wüdet ihr das machen?
  • _OnNodeChange ist sozusagen XML.OnChange und was darin passiert, soll keinen Einfluß auf den restlichen Programmablauf haben, aber dennoch soll diese Exception auch nicht still und heimlich verschwinden oder "nur" via ShowException rausgehn, welches ach nur die Exception anzeigt
  • Meine nachfollgende Behandlung soll nicht unterbrochen werden, also MUß ich ja die Exception abfangen.
  • aber dennoch soll in z.B. in Application.OnException etwas ankommen
    (direkt Application.OnException anzusprechen kommt nicht in Frage)
    • denn a) hab ich die Forms-Unit nicht bei mir integriert
    • und b) könnte ja eine andere Execeptio-Behandlung z.B. ala MadExcept installiert sein


PS: ShowMessage macht nix Anderes als dieses (funktionelle Kurzfassung von SysUtils.ShowException)
Delphi-Quellcode:
procedure ShowException(ExceptObject: TObject; ExceptAddr: Pointer);
begin
  if IsConsole then
    WriteLn(ExceptObject.Message)
  else
    ShowMessage(ExceptObject.Message);
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat