Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Exception richtig behandeln (https://www.delphipraxis.net/141185-exception-richtig-behandeln.html)

TheReaper 4. Okt 2009 21:11

Re: Exception richtig behandeln
 
Nur so als Hinweis: alle StrToXXX Konverter Funktionen können die selbe Exception werfen wie bei StrToDate. Dafür gibts immer die passende TryStrToXXX Funktion. :warn:

Jens Hartmann 5. Okt 2009 07:16

Re: Exception richtig behandeln
 
Zitat:

Zitat von TheReaper
Nur so als Hinweis: alle StrToXXX Konverter Funktionen können die selbe Exception werfen wie bei StrToDate. Dafür gibts immer die passende TryStrToXXX Funktion.

:thumb:

Danke für die Info. Ich denke, das ich das in alle meine Funktionen noch integrieren werde.

Gruß Jens

Jens Hartmann 8. Nov 2009 14:57

Re: Exception richtig behandeln
 
Hallo,

ich bin immer noch dabei meine Exceptionbehandlungen zu ergänzen. Ist es OK, wenn ich am Anfang meiner Funktion, in der verschiedene Fehler auftreten können, Umwandlungen von Zeit in String oder String in Integer etc. in einem großen gemeinsamen

Delphi-Quellcode:
try

except
Block packe. Und wäre es OK, wenn der
Delphi-Quellcode:
except
Teil dann leer ist. Wenn ich wie unten das so machen würde, dann wäre ja im except Block keine Anweisung notwendig, da ja der obere
Delphi-Quellcode:
try
Block komplett abgebrochen wird. Also denke ich brauche ich auch kein Rollback und so.

Delphi-Quellcode:
procedure TForm1.TreeViewResultMB100(ParserTreeViewMB100: TMyBaseParser);
var
  Daten : TOMBSerie;
begin
try
  QryMB100.Close;
  QryMB100.SQL.Text := 'INSERT INTO MB100'+
      '(LFDNR, DATUM, UHRZEIT, EREIGNIS, TEILNEHMER, BEREICH)'+
      'VALUES(:LfdNr,:Datum,:Uhrzeit,:Ereignis,:Teilnehmer,:Bereich)';

  QryMB100.ParamByName('Lfdnr').AsInteger := ParserTreeViewMB100.EntriesMB100[0].LfdNr;
  QryMB100.ParamByName('Datum').AsDate := StrToDate(ParserTreeViewMB100.EntriesMB100[0].Datum);
  QryMB100.ParamByName('Uhrzeit').AsTime := StrToTime(ParserTreeViewMB100.EntriesMB100[0].Uhrzeit);
  QryMB100.ParamByName('Ereignis').AsString := ParserTreeViewMB100.EntriesMB100[0].Ereignis;
  QryMB100.ParamByName('Teilnehmer').AsString := ParserTreeViewMB100.EntriesMB100[0].Teilnehmer;
  QryMB100.ParamByName('Bereich').AsString := ParserTreeViewMB100.EntriesMB100[0].Bereich;

  QryMB100.ExecSQL;
  ConSecurdat.Commit;

  QryMB100.Close;
  QryMB100.SQL.Text := 'Select Max(ID) As ID From MB100';
  QryMB100.Open;

  VST.BeginUpdate;
  Daten := TOMBSerie.Create;
  with Daten do
  begin
    Daten.ID := QryMB100.FieldByName('ID').AsInteger;
    Daten.LfdNr := ParserTreeViewMB100.EntriesMB100[0].LfdNr;

    Daten.Datum := ParserTreeViewMB100.EntriesMB100[0].Datum;
    Daten.Uhrzeit := ParserTreeViewMB100.EntriesMB100[0].Uhrzeit;

    Daten.Ereignis := ParserTreeViewMB100.EntriesMB100[0].Ereignis;

    Daten.Teilnehmer := ParserTreeViewMB100.EntriesMB100[0].Teilnehmer;

    Daten.Bereich := ParserTreeViewMB100.EntriesMB100[0].Bereich;
  end;
  VST.AddChild(nil, Daten);

  if VST.RootNodeCount >= 4001 then
          begin
            VST.DeleteNode(VST.GetFirst);
          end;
  VST.EndUpdate;
  VST.ScrollIntoView(VST.GetLast, true);

  QryMB100.Close;
  DataMB256plus := '';
except

end;
end;
Danke schon mal Gruss


Jens

jaenicke 8. Nov 2009 18:15

Re: Exception richtig behandeln
 
Ein leerer except-Block sieht aber komisch aus. Wie wäre es, wenn du den Benutzer darüber informierst, dass da etwas schief gegangen ist?

Das ist bei dir ein wenig so als ob bei einem Auto der Reifen überhitzt, der Bordcomputer das feststellt, aber trotzdem nur die Lüftungszufuhr verschließt, damit im Auto der Rauch nicht stört... (bis der Reifen platzt)

Jens Hartmann 8. Nov 2009 18:59

Re: Exception richtig behandeln
 
Das Problem, ist eigendlich das mich der Teil normalerweise nicht interesiert.

Sollte in dem
Delphi-Quellcode:
try
Block ein Exception auftreten, entsteht diese zu 99,9% bei einem RESET der Hardware, da der dann folgende 1.Datensatz unterumständen nicht Ordnungsgemäß ist. Das soll heißen, das bei 100000 Datensätzen, das eventuell das bei einem mal passieren kann.

Gut wenn eine unerwartet Exception auftritt, wäre es eventuell Sinnvoll. Dann müsste ich dies vieleicht in ein Fehlerprotokoll oder so schreiben.

Ist es den ansonsten OK, den
Delphi-Quellcode:
try except
Block über die gesamte Funktion zu legen.

MFG

Jens

jaenicke 8. Nov 2009 19:05

Re: Exception richtig behandeln
 
Ja, gut, wenn das normal ist, dass die Daten nicht immer korrekt analysiert werden können, dann braucht man das nicht anzeigen. Allerdings wäre es dann umso sinnvoller wie bereits angesprochen zuerst zu prüfen, ob die Daten valide sind bevor diese einfach eingetragen werden bzw. das versucht wird. Die Try... Funktionen wurden ja angesprochen und ich hatte gedacht du wolltest das auch entsprechend umbauen?

Zitat:

Zitat von Jens Hartmann
Ist es den ansonsten OK, den
Delphi-Quellcode:
try except
Block über die gesamte Funktion zu legen.

Ich würde es zumindest soweit trennen, dass ein Fehler beim Parsen ignoriert wird, ein Fehler beim Eintragen in die Datenbank z.B. aber vielleicht doch behandelt werden sollte (also in einem weiteren Exception-Block). Denn da sollte dann ja wohl keine Exception auftreten. Und wenn doch, könnte das ein Problem darstellen, oder?

Jens Hartmann 8. Nov 2009 19:13

Re: Exception richtig behandeln
 
Ja, das stimmt wohl. Ich werde das jetzt mal umschreiben und dann mal hier einstellen.

Danke erstmal

Gruß Jens

Jens Hartmann 7. Jan 2010 22:47

Re: Exception richtig behandeln
 
Hallo mal wieder zusammen, :chat:

ich will mal wieder ein altes Thema von mir aufleben lassen. Ich habe vor kurzer Zeit ein wenig an meinen Exceptionbehandlungen gearbeitet. Ich habe mich nochmal in das Thema eingelesen und einen Teil von meinem Programm angefangen auf meine Kenntnisse anzupassen. Da ich aber jetzt nicht unnötig arbeiten will und gerne mal Eure Meinung hören würde, wäre es schön wenn ihr mal kurz zu dem folgenden Code Eure Meinung sagen könnte. :idea:

Delphi-Quellcode:
{HTML in Datei speichern}
function THTMLExportForm.SaveHTML(HTMLFile : TStringlist):string;
begin
  if SaveDialog1.Execute then
    HTMLFile.SaveToFile(SaveDialog1.FileName);
    Result := SaveDialog1.FileName;
end;

{HTML-Datei für MB-Serie erstellen}
procedure THTMLExportForm.HTMLErzeugenMBSerie;
Var
  slHTML : TStringList;
  i : integer;
  mrResult: Integer;
  FileName : String;
begin
  try  //start try Block mit finally für HTML.Free
    try //start try Block Erstellung HTML
      slHTML := TStringList.Create;

      slHTML.Add('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"');
      slHTML.Add('<html>');

      slHTML.Add('<head>');
      slHTML.Add('<link rel="stylesheet" type="text/css" href="MB.css"');
      slHTML.Add('<Style type="text/css"></style>');
      slHTML.Add('<title>Protokolldatei</title>');
      slHTML.Add('</head>');

      slHTML.Add('<body>');
      slHTML.Add('<img src= ".\Kopf1.bmp" width= "900" height= "150" align= "rigth" alt= "Titel" >');
      slHTML.Add('<h1 style="color:#FFFFFF; background-color:#000080; align= "right">Firma hartmann & uebach Nachrichtentechnik GmbH</h1>');
      slHTML.Add('<h1 style="color:#000080;">Objekt: '
                 +QryVorgabe.FieldByName('KUNDEOBJEKT').AsString+'</h1>');
      slHTML.Add('<table border="0" style="border-collapse:separate;"'+
                 'width="100%" style="'+
                 'border-left:5px solid #000080;border-right:5px solid #000080;'+
                 'border-top:5px solid #000080;border-bottom:5px solid #000080;>');
      slHTML.Add('<tr>');
      slHTML.Add('<th align="left">Protokolldatei vom '+DateTimeToStr(Now)+'</th>');
      slHTML.Add('<th align="left">ID</th>');
      slHTML.Add('<th align="left">LfdNr</th>');
      slHTML.Add('<th align="left">Datum</th>');
      slHTML.Add('<th align="left">Uhrzeit</th>');
      slHTML.Add('<th align="left">Ereignis</th>');
      slHTML.Add('<th align="left">Teilnehmer</th>');
      slHTML.Add('<th align="left">Bereich</th>');
      slHTML.Add('<tr>');
      for i := 0 to QryHTML.RecordCount -1 do
        begin
          slHTML.Add('<tr class="' + QryHTML.FieldByName('Ereignis').AsString + '">');
          slHTML.Add('<td>');
          slHTML.Add(IntToStr(QryHTML.FieldByName('ID').AsInteger));
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(IntToStr(QryHTML.FieldByName('LfdNr').AsInteger));
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(DateToStr(QryHTML.FieldByName('Datum').AsDateTime));
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(TimeToStr(QryHTML.FieldByName('Uhrzeit').AsDateTime));
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(QryHTML.FieldByName('Ereignis').AsString);
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(QryHTML.FieldByName('Teilnehmer').AsString);
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(QryHTML.FieldByName('Bereich').AsString);
          slHTML.Add('</td>');
          slHTML.Add('</tr>');
          QryHTML.Next;
        end;
      slHTML.Add('</table>');
      slHTML.Add('</body>');
      slHTML.Add('</html>');
    except //Ende try Block Exceptionbehandlung Erstellung HTML
      ShowMessage('HTML Dokument konnte nicht erstellt werden');
    end;  //Ende try Block end Erstellen HTML
    try   //Start try Block Speichern
      FileName := SaveHTML(slHTML);
    except //Ende try Block Exceptionbehandlung Speichern
      ShowMessage('Datei konnte nicht gespeichert werden');
    end;  //Ende try Block end Speichern
    try   //Start try Block Datei Öffnen
      if AnzeigenCheckBox.Checked then
        ShellExecute(Application.Handle, 'open', PAnsiChar(FileName), nil, nil, SW_ShowNormal);
    except //Ende try Block Exceptionbehandlung Öffnen
      ShowMessage('Datei konnte nicht geöffnet werden');
    end;  //Ende try Block end Öffnen
    try   //Start try Block Datei EMail versenden
      if VersendenCheckBox.Checked then
        SendMail(FileName);
    except //Ende try Block Exceptionbehandlung EMail versenden
      ShowMessage('Datei konnte nicht als E-Mail versendet werden');
    end;  //Ende try Block end EMail versenden
    try   //Start try Block Datei Drucken
      if DruckenCheckBox.Checked then
        ShellExecute(handle, 'print', PAnsiChar(FileName), '', '', SW_HIDE);
    except //Ende try Block Exceptionbehandlung Drucken
      ShowMessage('Datei konnte nicht gedruckt werden');
    end;  //Ende try Block end Drucken
  finally //Ende try Block TStringlist über finally wieder freigeben
    slHTML.Free;
  end;    //Ende try Block finally
end;
Danke schon mal und Gruß

Jens

sx2008 8. Jan 2010 06:44

Re: Exception richtig behandeln
 
Folgender Code hat gleich drei Fehler:
Delphi-Quellcode:
try   //Start try Block Datei EMail versenden
  if VersendenCheckBox.Checked then
      SendMail(FileName);
except //Ende try Block Exceptionbehandlung EMail versenden
   ShowMessage('Datei konnte nicht als E-Mail versendet werden');
end;  //Ende try Block end EMail versenden
1.) Fehler
die ursprüngliche Exception-Meldung geht verloren.
Die Funktion SendMail() kann (wenn sie was taugt) wertvolle Hinweise gegeben, WESHALB die EMail nicht gesendet werden konnte.
Es wäre doch wirklich dumm, diese Information einfach so wegzuwerfen.

2.) Fehler
Verwendung von ShowMessage.
Wenn obiger Try..except Block innerhalb einer Schleife aufgerufen wird und es zum Fehler kommt,
dann viel Spass beim Wegklicken der Fehlermeldungen.
Oftmals bleibt nichts anderes übrig, als das Programm mit dem Taskmanager abzuschiesen.

3.) Fehler
Deine Kommentare sind nichts anderes als visuelles Störfeuer!
Es ist sinnlos und kontraproduktiv das Offensichtliche zu kommentieren.

Viel besser wäre:
Delphi-Quellcode:
try
  if VersendenCheckBox.Checked then
      SendMail(FileName);
except
  on E:Exception do
  begin
     Exception.Message := 'Datei konnte nicht als E-Mail versendet werden'#13#10+
       Exception.Message;
     raise;
  end;
end;

Jens Hartmann 8. Jan 2010 14:46

Re: Exception richtig behandeln
 
Zitat:

Zitat von sx2008
Folgender Code hat gleich drei Fehler:

Ich habe das mal geändert. Wäre das jetzt so OK. Hier jetzt mal mit den Funktionen "SendMail()" und "SaveHTML()"...
Delphi-Quellcode:
{HTML-Datei für MB-Serie erstellen}
procedure THTMLExportForm.HTMLErzeugenMBSerie;
Var
  slHTML : TStringList;
  i : integer;
  mrResult: Integer;
  FileName : String;
begin
  try
    try
      slHTML := TStringList.Create;

      slHTML.Add('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"');
      slHTML.Add('<html>');

      slHTML.Add('<head>');
      slHTML.Add('<link rel="stylesheet" type="text/css" href="MB.css"');
      slHTML.Add('<Style type="text/css"></style>');
      slHTML.Add('<title>Protokolldatei</title>');
      slHTML.Add('</head>');

      slHTML.Add('<body>');
      slHTML.Add('<img src= ".\Kopf1.bmp" width= "900" height= "150" align= "rigth" alt= "Titel" >');
      slHTML.Add('<h1 style="color:#FFFFFF; background-color:#000080; align= "right">Firma hartmann & uebach Nachrichtentechnik GmbH</h1>');
      slHTML.Add('<h1 style="color:#000080;">Objekt: '
                 +QryVorgabe.FieldByName('KUNDEOBJEKT').AsString+'</h1>');
      slHTML.Add('<table border="0" style="border-collapse:separate;"'+
                 'width="100%" style="'+
                 'border-left:5px solid #000080;border-right:5px solid #000080;'+
                 'border-top:5px solid #000080;border-bottom:5px solid #000080;>');
      slHTML.Add('<tr>');
      slHTML.Add('<th align="left">Protokolldatei vom '+DateTimeToStr(Now)+'</th>');
      slHTML.Add('<th align="left">ID</th>');
      slHTML.Add('<th align="left">LfdNr</th>');
      slHTML.Add('<th align="left">Datum</th>');
      slHTML.Add('<th align="left">Uhrzeit</th>');
      slHTML.Add('<th align="left">Ereignis</th>');
      slHTML.Add('<th align="left">Teilnehmer</th>');
      slHTML.Add('<th align="left">Bereich</th>');
      slHTML.Add('<tr>');
      for i := 0 to QryHTML.RecordCount -1 do
        begin
          slHTML.Add('<tr class="' + QryHTML.FieldByName('Ereignis').AsString + '">');
          slHTML.Add('<td>');
          slHTML.Add(IntToStr(QryHTML.FieldByName('ID').AsInteger));
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(IntToStr(QryHTML.FieldByName('LfdNr').AsInteger));
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(DateToStr(QryHTML.FieldByName('Datum').AsDateTime));
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(TimeToStr(QryHTML.FieldByName('Uhrzeit').AsDateTime));
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(QryHTML.FieldByName('Ereignis').AsString);
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(QryHTML.FieldByName('Teilnehmer').AsString);
          slHTML.Add('</td>');
          slHTML.Add('<td>');
          slHTML.Add(QryHTML.FieldByName('Bereich').AsString);
          slHTML.Add('</td>');
          slHTML.Add('</tr>');
          QryHTML.Next;
        end;
      slHTML.Add('</table>');
      slHTML.Add('</body>');
      slHTML.Add('</html>');
    except
      on e : Exception do begin
        TForm1.Servicememo.Lines.Add(e.Message);
      raise;
      end;
    end;

    try
      FileName := SaveHTML(slHTML);
    except
      on e : Exception do begin
        e.Message := 'Datei konnte nicht gespeichert werden'#13#10+e.Message;
      raise;
      end;
    end;

    try
      if AnzeigenCheckBox.Checked then
        ShellExecute(Application.Handle, 'open', PAnsiChar(FileName), nil, nil, SW_ShowNormal);
    except
      on e : Exception do begin
        e.Message := 'Datei konnte nicht geöffnet werden'#13#10+e.Message;
      raise;
      end;
    end;

    try
      if VersendenCheckBox.Checked then
        SendMail(FileName);
    except
      on e : Exception do begin
        e.Message := 'Datei konnte nicht als E-Mail versendet werden'#13#10+e.Message;
      raise;
      end;
    end;

    try
      if DruckenCheckBox.Checked then
        ShellExecute(handle, 'print', PAnsiChar(FileName), '', '', SW_HIDE);
    except
      on e : Exception do begin
        e.Message := 'Datei konnte nicht gedruckt werden'#13#10+e.Message;
      raise;
      end;
    end;

  finally
    slHTML.Free;
  end;
end;

{HTML in Datei speichern}
function THTMLExportForm.SaveHTML(HTMLFile : TStringlist):string;
begin
  if SaveDialog1.Execute then
    HTMLFile.SaveToFile(SaveDialog1.FileName);
    Result := SaveDialog1.FileName;
end;

{HTML-Datei als E-Mail versenden}
procedure THTMLExportForm.SendMail(HTMLFileName : String);
var
  Attachment : TStringList;
  i : integer;
begin
  try
    QryVorgabe.Close;
    QryVorgabe.SQL.Text := 'SELECT * FROM VORGABE';
    QryVorgabe.Open;
  except
    on e : Exception do
      begin
        e.Message := 'Datenbank konnte nicht geöffnet werden'#13#10+e.Message;
      raise;
    end;
  end;

  try
    Attachment := TStringList.Create;
    Attachment.Add(HTMLFileName);
    Attachment.Add('.\Kopf1.bmp');
      with mesgMessage do begin
        Clear;
        From.Text := QryVorgabe.FieldByName('EIGENE_E_MAIL').AsString;
        Recipients.Add.Text := AnEMailEdit.Text;
        Subject := BetreffEdit.Text;
        Body.Assign(EMailMemo.Lines);
          if FileExists(HTMLFileName) then
            begin
              if assigned(Attachment) then
                for i := 0 to Attachment.Count - 1 do
                  TIdAttachmentFile.Create(MessageParts, Attachment.Strings[i]);
            end
      end;

      with smtpSendMail do begin
        Username := QryVorgabe.FieldByName('BENUTZERNAME_E_MAIL').AsString;
        Password := QryVorgabe.FieldByName('PASSWORT_E_MAIL').AsString;
        Host := QryVorgabe.FieldByName('SMTP_SERVER').AsString;
        Connect;
      try
        Send(mesgMessage);
      finally
        Disconnect;
      end;
    end;
    showmessage('Mail wurde erfolgreich an folgende Adressen versendet.'+sLineBreak+sLineBreak+
                    'An:  '+AnEMailEdit.Text);
  finally
    Attachment.Free;
  end;
  QryVorgabe.Close;
end;
Kann ich dann eigendlcih auch einfach einen
Delphi-Quellcode:
try..except
Block für die gesamten Anweisung nehmen und das ganze dann so machen...

Delphi-Quellcode:
{HTML-Datei für MB-Serie erstellen}
procedure THTMLExportForm.HTMLErzeugenMBSerie;
Var
  slHTML : TStringList;
  i : integer;
  mrResult: Integer;
  FileName : String;
begin
  try
    try
      slHTML := TStringList.Create;

      slHTML.Add('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"');
      slHTML.Add('<html>');
      ....
      ....
      if VersendenCheckBox.Checked then
        SendMail(FileName);
      ....
      ....
      if DruckenCheckBox.Checked then
        ShellExecute(handle, 'print', PAnsiChar(FileName), '', '', SW_HIDE);
    except
      on e : Exception do begin
        Memo1.Lines.Add := 'Fehler beim erstellen der Datei';
        Memo1.Lines.Add := 'Fehler aufgetreten: '+e.Message;
      if FehlerCheckBox.Cheched then
        raise; //Wenn CheckBox Fehleranzeigen aktiv, wird der Fehler angezeigt, ansonsten nur Eintrag im Memo
      end;
    end;

  finally
    slHTML.Free;
  end;
end;
Das müsste doch so auch gehen...

Gruß Jens


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:45 Uhr.
Seite 3 von 4     123 4      

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