![]() |
Exception richtig behandeln
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo zusammen,
ich habe mal eine Frage zur Behandlung von Exceptions. Ich lese Daten aus einer Textdatei in eine Datenbank ein. Wenn jetzt z.B. Das eingelesen Datum kein gültigen Datumswert hat, wird natürlich eine Meldung beim eintragen in die Datenbank erzeugt, die mir sagt, '' ist kein gültiges Datum. (siehe Anhang). Wie kann ich jetzt in mein Commit eine sauber Exeptionbehandlung einbauen, die diese Datensätze einfach nicht übernimmt. Probiert habe ich das ganz so, funktioniert aber leider nicht.
Delphi-Quellcode:
Danke schon mal und Gruß
VST.BeginUpdate;
for i := 0 to High(Parser.EntriesMB256) do begin Daten := TOMBSerie.Create; with Daten do begin DM_PS.Qry_InsertMB256.Close; DM_PS.QryImportMB256.ParamByName('LfdNr').AsInteger := Parser.EntriesMB256[i].LfdNr; DM_PS.QryImportMB256.ParamByName('Datum').AsDate := StrToDate(Parser.EntriesMB256[i].Datum); DM_PS.QryImportMB256.ParamByName('Uhrzeit').AsTime := StrToTime(Parser.EntriesMB256[i].Uhrzeit); DM_PS.QryImportMB256.ParamByName('Ereignis').AsString := Parser.EntriesMB256[i].Ereignis; DM_PS.QryImportMB256.ParamByName('Teilnehmer').AsString := Parser.EntriesMB256[i].Teilnehmer; DM_PS.QryImportMB256.ParamByName('Bereich').AsString := Parser.EntriesMB256[i].Bereich; DM_PS.QryImportMB256.ExecSQL; try DM_PS.ConPSSecur.Commit; DM_PS.QrySelectMaxIDMB256.Open; except on e : Exception Do begin ShowMessage(e.Message); end; end; Daten.ID := DM_PS.QrySelectMaxIDMB256.FieldByName('ID').AsInteger; Daten.LfdNr := Parser.EntriesMB256[i].LfdNr; Daten.Datum := Parser.EntriesMB256[i].Datum; Daten.Uhrzeit := Parser.EntriesMB256[i].Uhrzeit; Daten.Ereignis := Parser.EntriesMB256[i].Ereignis; Daten.Teilnehmer := Parser.EntriesMB256[i].Teilnehmer; Daten.Bereich := Parser.EntriesMB256[i].Bereich; end; VST.AddChild(nil, Daten); DM_PS.QrySelectMaxIDMB256.Close; Label6.Caption := IntToStr(StrToInt(Label6.Caption)+1); ProgBarDatei.Position := ID; Inc(ID); VST.ScrollIntoView(VST.GetLast, true); VST.EndUpdate; DM_PS.QrySelectMaxIDMB256.Close; end; end; Jens |
Re: Exception richtig behandeln
Der Fehler tritt ja beim StrToDate auf, das jedoch fängst du gar nicht ab. Du solltest lieber mit TryStrToDate usw. arbeiten, dann kannst du bei nicht erfolgreicher Umwandlung auch die Eintragung gar nicht erst versuchen.
|
Re: Exception richtig behandeln
Grundsätzlich sollten solche Funktionen nur mit garantiert gültigen Parametern aufgerufen werden. Das bedeutet für Dich, das du eine Sicherheitsschicht um diese eigentliche Funktion bauen musst. Diese Sicherheitsschicht nimmt die Parameter entgegen, prüft sie und wirft ggf eine Exception. Erst bei Korrektheit wird die Funktion aufgerufen. Diese kann dann wieder Fehler verursachen, die dann aber isoliert und 'in Ruhe' betrachtet werden können.
|
Re: Exception richtig behandeln
Ich würde an deiner Stelle eine StringListe erzeugen oder der Funktion von Aussen übergeben um darin alle Fehlermeldungen zu sammeln.
Delphi-Quellcode:
Die Fehlerliste wird dem Benutzer am Ende präsentiert ohne dass der Benutzer jeden Fehler einzeln quittieren muss.
except
on e : Exception Do begin fehlerliste.Add(Format('Entry %d: %s|%s',[i, e.Classname, e.Message])); end; end; (ein riesen Vorteil, wenn es mal 50 oder mehr Fehler werden sollten) Ausserdem wird auch die Entry-Nummer festgehalten; das ist wichtig, wenn man die Ursache der Fehler herausfinden möchte. |
Re: Exception richtig behandeln
Hallo,
also irgendwie zue ich mir mit Exceptionbehandlungen noch sehr schwer. Ich habe die jetzt geändert, aber der Fehler ist immer noch da. Hier mal mein neuer Code.
Delphi-Quellcode:
Vieleicht kann mir ja mal jemand sagen, wo der Fehler liegt, und mal erklären, wie ich am besten an eine solch Try/Except Sache dran gehe.
try
DM_PS.Qry_InsertMB256.Close; DM_PS.QryImportMB256.ParamByName('LfdNr').AsInteger := Parser.EntriesMB256[i].LfdNr; DM_PS.QryImportMB256.ParamByName('Datum').AsDate := StrToDate(Parser.EntriesMB256[i].Datum); DM_PS.QryImportMB256.ParamByName('Uhrzeit').AsTime := StrToTime(Parser.EntriesMB256[i].Uhrzeit); DM_PS.QryImportMB256.ParamByName('Ereignis').AsString := Parser.EntriesMB256[i].Ereignis; DM_PS.QryImportMB256.ParamByName('Teilnehmer').AsString := Parser.EntriesMB256[i].Teilnehmer; DM_PS.QryImportMB256.ParamByName('Bereich').AsString := Parser.EntriesMB256[i].Bereich; DM_PS.QryImportMB256.ExecSQL; DM_PS.ConPSSecur.Commit; except on e : Exception Do begin Fehlerliste.Add(Format('Entry %d: %s|%s',[i, e.Classname, e.Message])); end; end; Danke schon aml Gruß Jens |
Re: Exception richtig behandeln
Liste der Anhänge anzeigen (Anzahl: 1)
Was heißt der Fehler ist noch da? Dass Delphi den anzeigt, wenn du das Programm aus Delphi startest? Das passiert immer, wenn der Debugger aktiv ist.
Um das zu verhindern, kannst du (wenn der Fehler angezeigt wird) dessen Anzeige einfach mit der CheckBox deaktivieren. (Siehe Anhang) Oder einfach das Programm nicht aus Delphi sondern separat starten (Menü Start --> Ohne Debugger ausführen). // EDIT: Auf TryStrToDate stattdessen habe ich ja schon hingewiesen, das wäre noch besser... |
Re: Exception richtig behandeln
Liste der Anhänge anzeigen (Anzahl: 3)
Das ist mir schon klar.
Der Fehler, kommt aber auch, wenn ich ohne Debugger ausführe, da ja ein Fehler vorhanden ist. Ich muss ja realisieren, wodurch der Fehler kommt, um diesen dann auszuschliessen. Nur wenn ich im Debugger auf Anhalten klicke, um an die Stelle im Code zu gelangen, wo der Fehler passiert, lande ich irgendwo im Quellcode der ZEOS Kompo und wieß jetzt nicht, wie ich anfangen kann diesen Abzufangen. Hier nochmal die Fehlermeldungen und der Code in dem ich bei Anhalten lande.
Delphi-Quellcode:
procedure CheckInterbase6Error(PlainDriver: IZInterbasePlainDriver;
StatusVector: TARRAY_ISC_STATUS; LoggingCategory: TZLoggingCategory = lcOther; SQL: string = ''); var Msg: array[0..1024] of Char; PStatusVector: PISC_STATUS; ErrorMessage, ErrorSqlMessage: string; ErrorCode: LongInt; begin if (StatusVector[0] = 1) and (StatusVector[1] > 0) then begin ErrorMessage:=''; PStatusVector := @StatusVector; while PlainDriver.isc_interprete(Msg, @PStatusVector) > 0 do ErrorMessage := ErrorMessage + ' ' + StrPas(Msg); ErrorCode := PlainDriver.isc_sqlcode(@StatusVector); PlainDriver.isc_sql_interprete(ErrorCode, Msg, 1024); ErrorSqlMessage := StrPas(Msg); {$IFDEF INTERBASE_EXTENDED_MESSAGES} if SQL <> '' then SQL := Format(' The SQL: %s; ', [SQL]); {$ENDIF} if ErrorMessage <> '' then begin DriverManager.LogError(LoggingCategory, PlainDriver.GetProtocol, ErrorMessage, ErrorCode, ErrorSqlMessage + SQL); {$IFDEF INTERBASE_EXTENDED_MESSAGES} raise EZSQLException.CreateWithCode(ErrorCode, Format('SQL Error: %s. Error Code: %d. %s', [ErrorMessage, ErrorCode, ErrorSqlMessage]) + SQL); Zitat:
MFG jens |
Re: Exception richtig behandeln
Hallo Jens,
Exception 2: Erklärt sich von selbst. irgendwo, wo ein Date Wert sein sollte ist nix. Exception 1: Kommt ganz gern, wenn die Länge des Strings die Feldgröße überschreitet. die Zugriffsverletztung :gruebel: |
Re: Exception richtig behandeln
Zitat:
Delphi-Quellcode:
// EDIT:
var
DateValue: TDate; begin ... if not TryStrToDate(DeinString, DateValue) then begin ShowMessage('Fehler bei Umwandlung von ' + DeinString + ' in einen Datumswert'); Exit; // abbrechen oder so end; ... // Wenn alles erfolgreich war, dann die Werte benutzen: DateValue ... Ja, ich weiß, Exit ist nicht unbedingt ein schöner Programmfluss, kann man natürlich auch umgekehrt formulieren. Zu den SQL-Fehlern sage ich mangels Erfahrung lieber nix. :mrgreen: |
Re: Exception richtig behandeln
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:51 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-2025 by Thomas Breitkreuz