Frage

In einigen Delphi 7 Code, den ich beibehalten bin, habe ich eine Menge von Instanzen der folgenden bemerkt:

with ADOQuery1 do begin
  // .. fill out sql.text, etc
  try
    execSQL;
  except
    raise;
  end;
end;

Es scheint mir, dass diese versuchen Blöcke entfernt werden konnten, da sie nichts zu tun. Ich bin aber vorsichtig möglich subtile Nebenwirkungen ..

Kann jemand denken Sie an irgendwelchen Fällen, in denen diese Blöcke tatsächlich etwas tun konnte, die nicht ohne sie dort passieren würde?

War es hilfreich?

Lösung

In diesem Zusammenhang hat die Erhöhung Betrieb keine Wirkung und soll becuase sein einfach wieder Anheben die Ausnahme entfernt werden, dass der Ausnahmeblock gerade gefangen. erhöhen wird typischerweise auf die Steuerung an das Ende des Blocks verwendet wird, wenn keine entsprechende Fehlerbehandlung zur Verfügung steht. Im folgenden behandeln wir die benutzerdefinierte Ausnahme, aber jede andere Ausnahme sollte an anderer Stelle behandelt werden.

try
  someOperation;
except
  on e: ECustomException do
    SomeCustomHandelr;
  else
     begin
       // the raise is only useful to rethrow the exception to an encompasing 
       // handler.  In this case after I have called my logger code. as Rob
       // mentioned this can be omitted if you arent handling anything because
       // the compiler will simply jump you to the next block if there is no
       // else.
       LogUnexpectedException('some operation failed',e);
       raise;
     end;
end;

Achten Sie darauf, dass es ähnlich aussehende Form ohne die „Erhöhung“, dass die Nebenwirkung des Essens hat / alle Ausnahmen zu verstecken. practicies durch sehr skrupellose Entwickler, die hoffentlich bewegt haben, mit der Konkurrenz Positionen auf.

with ADOQuery1 do begin  
  // .. fill out sql.text, etc  
  try    
    execSQL; 
  except
    // no handler so this just eats any "errors"    
  end;

Andere Tipps

die außer Code Entfernen oben Code-Snippet wird keinen Unterschied machen. Sie können (und ich glaube, Sie sollte , da sie die Lesbarkeit reduziert) entfernen.

Okay, wirklich zwei Fragen hier.

Zuerst es ist sinnvoll: Wenn ExecSQL eine Ausnahme auslöst, wird es durch den try-Block gefangen und an die außer weitergeleitet. Dann wird es durch die Erhöhung auf den nächsthöheren Block weitergeleitet.

Zweitens ist es nützlich ? Wahrscheinlich nicht. Es ist mit ziemlicher Sicherheit das Ergebnis eines von drei Dingen:

  1. Jemand mit spitzem Haare hat einen Codierungsstandard, auf die „alle Operationen, die eine Ausnahme auslösen können in einem try-Block sein muss.“
  2. Jemand meinte, zurückzukommen und die Ausnahmen von der execSQL statment in eine andere, sinnvoller, Ausnahme zu machen.
  3. Jemand neu war nicht bewusst, dass das, was sie geschrieben hat, war isomorph die uter Umwelt Sorge um die Ausnahme zu lassen, und so dachte sie muss es weiter.

ich ein bisschen schnell beantwortet haben, sehen am Ende ...
Wie es ist, ist es nutzlos für die Anwendung .
Zeitraum!

Jetzt auf dem „Warum“ Seite. Es kann sein, die Ausnahmen zu standardisieren, wenn Handhabung / war / wird / ist in anderen Orten / irgendeine Art von Logging-Code vor der Erhöhung eingefügt:

  try
    execSQL;
  except
    // Log Exception..
    on E: Exception do
    begin
      LogTrace(Format('%s: Exception Message[%s]',[methodname, E.Message]));
      raise;
    end;
  end;

oder für Cleanup Code:

  try
    execSQL;
  except
    //some FreeAndNil..
    raise;
  end;

Aktualisieren : Es wäre ein Fall, wo ich gerade etwas Gebrauch sehen würde, wie es ist ...
... in der Lage sein einen Haltepunkt auf der raise Spiel zu setzen, eine Chance zu bekommen, um zu sehen, was an diesem Block von Code im Kontext vor sich geht.

Dieser Code tut nichts, außer dem ursprüngliche Programmierer zu ermöglichen, einen Haltepunkt zu setzen auf dem ‚Raise‘ und die Ausnahme näher in der Quelle zu der möglichen Ursache dafür zu sehen. In diesem Sinne ist es eine durchaus vernünftige Debug-Technik.

Eigentlich soll ich gepostet als Kommentar zu François der Antworten, aber ich weiß nicht, ist es möglich, formatierte Code dort einfügen :( Also ich bin Entsendung dies als Antwort.

2mghie:

  
    
      

Das zweite ist völlig unidiomatic, würde man schließlich stattdessen verwenden.

    
  

Nein, „endlich“ wird Bereinigungs Objekt immer. „Außer“ - nur auf Ausnahme. Betrachten wir den Fall Funktion, die schafft, füllt und geben ein Objekt:

function CreateObj: TSomeObj;
begin
  Result := TSomeObj.Create;
  try
    ... // do something with Result: load data, fill props, etc.
  except
    FreeAndNil(Result); // oops: bad things happened. Free object to avoid leak.
    raise;
  end;
end;

Wenn Sie „endlich“ da setzen - Funktion Null immer wieder zurückkehren. Wenn Sie überhaupt „versuchen“ Block weglassen - es wird Ressourcen bei Ausnahme Leck in „...“

.

P. S. Natürlich können Sie „endlich“ und überprüfen ExceptObj verwenden, aber ... ist nicht so hässlich?

Der Titel enthält eine recht große Frage, während seine Erklärung ein spezifischeres Beispiel gibt. Also, meine Beantwortung der Frage, wie es aus dem Beispiel geht, kann doubtly etwas Nützliches hinzufügen, was bereits hier gesagt worden ist.

Aber vielleicht Blorgbeard will ja wissen, ob es ist überhaupt sinnvoll try ... except raise; end. In Delphi 7, wenn ich mich richtig erinnere, Exit auslösen würde den finally Teil eines try-finally Blockes (als ob es eine Art von Ausnahme war). Jemand könnte ein solches Verhalten als ungeeignet für ihre Aufgabe, und mit Hilfe der Konstruktion in Frage ist durchaus eine Abhilfe.

Nur wäre es immer noch seltsam, da eine einzige raise; zu verwenden, aber dann sollten wir gesprochen haben, über Nützlichkeit statt Bedeutsamkeit , wie Charlie ordentlich beobachtet hat.

Dieser Code tut nichts, außer eine Ausnahme re-raisen, die allready, ohne dass dies außer Block versucht angehoben wird. Sie können es sicher entfernen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top