![]() |
Delphi-Version: XE
Fehlerbehandlung : Folgefehler ?
Moin,
sowas ist mir schon mehrmals untergekommen, daß ein Folgefehler die eigentliche Fehlermeldung geschrottet hat. Jetzt hab ich das nochmal und konnte diesmal den Verursacher rausfinden. Sollte man nun Folgefehler beachten, oder nicht? Eigentlich muß man ja nur den ersten Fehler behandeln und der Zweite ist auch weg, bzw. man müsste den ersten Fehler erstmal kennen, was schwerer wird, wenn der sich in einer größeren Funktion versteckt und man durch den Folgefehler nicht das Wo erkennen kann. [blabla] GridFilter werden gespeichert, später wieder geladen und können zwischen den Installationen synchronisiert werden. Die Spalten im Grid werden aus dem DataSet generiert und die Query kann über die Synchro angepasst werden. Der Filter greift nun auf eine Spalte zu, welche es inzwischen nicht mehr gibt. Beim Laden des Filters knallt es nun in ReadComponent (Column fehlt und Property kann nicht geladen werden) und beim Filter.EndUpdate oder Active=True wird auch nochmal auf diese (nichtexstierende=nil) Column zugegriffen und es knallt nochmal. [/blabla]
Delphi-Quellcode:
Der Kunde und auch wir sehen also erstmal nur das "Zugriffsverletzung" :cry:
//procedure TcxFilterCriteria.LoadFromStream(Data);
Filter.EndUpdate GridView.DataController.Filter.BeginUpdate; try Wrapper := TFilterWrapper.Create(nil); try Wrapper.Filter := GridView.DataController.Filter; Data.ReadComponent(Wrapper); ///// Stream-Lesefehler ///// finally Wrapper.Free; end; finally GridView.DataController.Filter.EndUpdate; ///// Zugriffsverletzung ///// end; Die aktuelle Lösung besteht nun also darin den Folgefehler zu unterdrücken.
Delphi-Quellcode:
//GridView.DataController.Filter.LoadFromStream(Data);
{$REGION 'TcxFilterCriteria.LoadFromStream'} // Am Ende von TStream.ReadComponent wird aus einem "Fehler beim Lesen von _1.Filter.Criteria: Stream-Lesefehler" // in TcxFilterCriteria.EndUpdate ein nichtssagendes "Zugriffsverletzung bei Adresse 0". Filter.EndUpdate GridView.DataController.Filter.BeginUpdate; try Wrapper := TFilterWrapper.Create(nil); try Wrapper.Filter := GridView.DataController.Filter; Data.ReadComponent(Wrapper); finally Wrapper.Free; end; finally //GridView.DataController.Filter.EndUpdate; if System.ExceptObject = nil then GridView.DataController.Filter.EndUpdate else try GridView.DataController.Filter.EndUpdate; except end; // tritt hier ein Folgefehler auf, dann würde die originale Fehlermeldung geschrottet. end; {$ENDREGION} GridView.DataController.Filter.Active := True;
Delphi-Quellcode:
Oder vielleicht besser gleich auch für alle anderen Codestellen?
procedure TcxFilterCriteria.LoadFromStream(AStream: TStream);
var AWrapper: TFilterWrapper; begin BeginUpdate; try AWrapper := TFilterWrapper.Create(nil); try AWrapper.Filter := Self; AStream.ReadComponent(AWrapper); finally AWrapper.Free; end; finally if System.ExceptObject = nil then EndUpdate else try EndUpdate; except end; // tritt hier ein Folgefehler auf, dann würde die originale Fehlermeldung geschrottet. end; end;
Delphi-Quellcode:
Als Pattern also irgendwie so?
procedure TcxFilterCriteria.EndUpdate;
begin Dec(FLockCount); if System.ExceptObject = nil then CheckChanges else try CheckChanges; except end; // tritt hier ein Folgefehler auf, dann würde die originale Fehlermeldung geschrottet. end;
Delphi-Quellcode:
Im Grunde müsste man jetzt noch bestimmte Sonderfälle beachten, wenn man eine allgemeine Lösung sucht, was aber bei uns erstmal nicht vorkommt. :stupid:
procedure TMyClass.EndUpdate;
var HasError: Boolean; begin HasError := System.ExceptObject <> nil; try .... except if not HasError then raise; end; end; //////////////////////////////////////////////////////////////// procedure TMyClass.EndUpdate; begin try .... except if not Assigned(PRaiseFrame(RaiseListPtr)^.NextRaise) then // Kürzer, aber funktioniert nicht bei PC_MAPPED_EXCEPTIONS raise; end; end; |
AW: Fehlerbehandlung : Folgefehler ?
Solche komischen Sachen muss man nur dann machen, wenn man etwas falsch implementiert hat, bzw. in so einem Ausnahmefall trotzdem noch etwas macht, bzw. etwas nicht korrekt zurücksetzt.
Delphi-Quellcode:
hinterlässt im Fehlerfall einen dangling Pointer.
procedure TForm1.DoLoadSomething( const AFilename : string );
begin FSomething.Free; FSomething := TSomething.CreateFromFile( AFilename ); // da kann es knallen end;
Delphi-Quellcode:
Die Kernfrage ist immer: Wie hinterlasse ich das System in einem Ausnahmefall. Und das will gut überlegt sein.
procedure TForm1.DoLoadSomething( const AFilename : string );
var newSomething: TSomething; begin newSomething := TSomething.CreateFromFile( AFilename ); // da kann es knallen try FSomething.Free; // da könnte es knallen FSomething := newSomething; except newSomething.Free; raise; end; end; |
AW: Fehlerbehandlung : Folgefehler ?
Nun ja, hier ist der Fehler doch der Ressourcenschutzblock ... lässt man den weg, ist alles OK. :lol:
Bzw. der Ressourcenschutzblock enthält selber Code, der zu einem Fehler führen kann. Wenn vorher alles OK war, dann möchte ich den natürlich sehen, aber ansonsten halt ganz gern den ersten/eigentlichen/ursprünglichen Fehler.
Delphi-Quellcode:
So geht es auch, aber Schön ist was Anderes.
try
MachWas; finally try RäumAuf; except end; end; Pssst :angle:
Delphi-Quellcode:
Hier gibt es zimindestens keinen ungültigen Zeiger.
procedure TForm1.DoLoadSomething( const AFilename : string );
begin FreeAndNil(FSomething); // hier kann es knallen, aber ist dennoch nil FSomething := TSomething.CreateFromFile( AFilename ); // da kann es auch knallen, aber egal end; Bei dir wird immer dafür gesorgt, dass es eine TSomething-Instanz gibt. :) |
AW: Fehlerbehandlung : Folgefehler ?
Zitat:
Delphi-Quellcode:
führt zu einem Fehler, weil vorher etwas falsch gemacht wurde.
EndUpdate
Delphi-Quellcode:
macht etwas, obwohl es gar nichts machen kann (ist ja ein Lesefehler). Das ist der eigentliche Fehler.
Data.ReadComponent(Wrapper);
Delphi-Quellcode:
procedure TForm1.DoLoadSomething( const AFilename : string );
begin FreeAndNil(FSomething); // hier kann es knallen, wenn uns jemand einen dangling pointer hinterlassen hat FSomething := TSomething.CreateFromFile( AFilename ); // da kann es knallen end; Zitat:
Delphi-Quellcode:
try
MachWas_AberNichtsKaputt; except RäumAuf; raise; end; |
AW: Fehlerbehandlung : Folgefehler ?
TReader liest halt bis dahin ein, wo es geknallt hatte, womit dann natürlich auch nur die Hälfte geladen wurde und es dann so "kaputt" bleibt. :?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:09 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz