Wie kann ich, welche Ausnahmen eine Delphi-Funktion herauszufinden, werfen könnte?

StackOverflow https://stackoverflow.com/questions/72562

  •  09-06-2019
  •  | 
  •  

Frage

Gibt es einen guten Weg, um herauszufinden, welche Ausnahmen eine Prozedur / Funktion in Delphi erhöhen kann (einschließlich es heißt Prozeduren / Funktionen)?

In Java müssen Sie immer, welche Ausnahmen erklären, die ausgelöst werden können, aber das ist nicht der Fall in Delphi, die nicht behandelte Ausnahmen führen könnte.

Gibt es Code-Analyse-Tools, die Ausnahmen erkennt nicht behandelte?

War es hilfreich?

Lösung

(Edit:. Es ist nun offensichtlich, dass die Vorlagefrage nur Design-Zeit-Kontrolle)

Neue Antwort:

Ich kann nicht sagen, ob es irgendwelche Werkzeuge sind dies für Sie zu überprüfen. Pascal Analyzer, für einen, nicht.

I können sagen Sie jedoch, dass in den meisten Delphi-Anwendungen, auch wenn es ein Tool, war dies für Sie zu überprüfen, würden Sie keine Ergebnisse erhalten.

Warum? Weil die Hauptnachrichtenschleife in TApplication.Run () alle Handle Wraps () ruft in einer Ausnahmebehandlungsblock, der alle Ausnahmetypen zu erreichen. So werden Sie in den meisten Anwendungen um 99,999% des Code Umgang mit impliziter / default Ausnahme haben. Und in den meisten Anwendungen wird diese Ausnahmebehandlung um 100% Ihres eigenen Code sein -. Das 0,001% des Code, der nicht in der Ausnahmebehandlung eingewickelt wird, wird das automatisch generierte Code sein

Wenn es ein Tool zur Verfügung, das für Sie zu überprüfen, müßten Sie umschreiben Application.run (), so dass es nicht die Ausnahmebehandlung enthält.

(vorherige Antwort: Der Handler Application.OnException Ereignis zugeordnet werden alle Ausnahmen zu fangen, die von anderen Exception-Handler nicht behandelt werden. Während dieser Laufzeit ist, und somit vielleicht nicht genau das, was Sie nach (es klingt wie Sie sie zur Entwurfszeit identifizieren wollen), tut es Ihnen zu stoppen lassen jede Ausnahme nicht an anderer Stelle behandelt. In Verbindung mit Werkzeugen wie die JCLDebug Sachen in dem Jedi Code Library , könnten Sie einen Stack-Trace melden sie an herauszufinden, wo und warum eine Ausnahme aufgetreten, die für weitere Untersuchungen erlauben würde, und das Hinzufügen von spezifischer Ausnahmebehandlung oder Prävention rund um den Schuldigen Code ... )

Andere Tipps

Meine Vermutung ist, dass Sie versuchen, wie Java zu machen Delphi verhalten, die nicht ein guter Ansatz ist. Ich würde raten, nicht zu viel über nicht behandelte Ausnahmen zu kümmern. Im schlimmsten Fall werden sie sprudeln den Ober Exception-Handler VCL und führen einen Dialog Windows-Meldung. In einer normalen Anwendung, werden sie die Anwendung nicht stoppen.

Gut geschriebener Code würde, die verschiedenen Ausnahmen dokumentiert heb-, damit Sie sie in einer sinnvollen Art und Weise handhaben können. Catch-all-Handler nicht zu empfehlen, da es wirklich keine Möglichkeit zu wissen, was zu tun ist, wenn Sie nicht wissen, warum eine Ausnahme ausgelöst wurde. Ich kann auch MadExcept sehr empfehlen.

Bis auf einen Scan auf dem „Höher“ Stichwort, es gibt kein Sprachkonstrukt in Delphi, die den flüchtigen Leser erzählt können, die Ausnahmen von einem Verfahren zu erwarten.

Zur Laufzeit könnte man einen allumfassenden Exception-Handler in jeder Methode hinzufügen, aber das ist nicht ratsam, da sie die Geschwindigkeit der Ausführung verlangsamen. (Und es umständlich ist zu tun).

Das Hinzufügen eines Ausnahmebehandlungsblock auf ein Verfahren wird einige Montageanleitung, um es hinzuzufügen (auch wenn die Ausnahme nicht ausgelöst wird), was bildet meßbaren langsam nach unten, wenn die Methode sehr häufig aufgerufen wird.

Es hat ein paar Bibliotheken existieren, die Ihnen bei der Analyse der Laufzeit Ausnahmen helfen können, wie MadExcept , < a href = "http://jcl.svn.sourceforge.net/viewvc/jcl/trunk/jcl/source/windows/JclDebug.pas?view=markup" rel = "nofollow noreferrer"> JclDebug und Eurekalog . Diese Tools können melden Sie sich alle Arten von Details über die Ausnahme, es ist sehr ratsam, einen von denen zu verwenden!

Die kurzen Antworten gibt es kein Werkzeug, das tut, was Sie sagen, und sogar ein Scan für das erhöhen Stichwort würden Sie nicht dorthin gelangen. EAccessViolation oder EOutOfMemory sind nur zwei von einer Reihe von Ausnahmen, die fast überall angehoben werden könnten.

Eine grundlegende Sache über Delphi ist die Ausnahmen sind hierarchisch aufgebaut: Alle definierten Sprache Ausnahmen stammen von Exception , obwohl es ist erwähnenswert, dass es tatsächlich möglich ist, jede zu erhöhen TObject Nachkomme.

Wenn Sie auf Fang jede Ausnahme, die in einem bestimmten Verfahren erhöht wird, nur wickeln Sie es in einem try / except Block, aber wie erwähnt wurde < em> dies nicht empfohlen wird .

// Other code . . . 
try
  SomeProcedure()
except  // BAD IDEA!
  ShowMessage('I caught them all!');
end;

Das wird alles fangen, auch Instanzen eines erhabenen TObject . Obwohl ich würde behaupten, dass dies selten die beste Vorgehensweise ist. Normalerweise wollen Sie ein verwenden try / finally Block und lassen Sie Ihren globalen Exception-Handler (oder eine letzte try / except Block), um tatsächlich die Ausnahmen zu behandeln.

Ich werde zweiten (oder ist es dritte) MadExcept . Ich habe es erfolgreich in mehreren kommerziellen Anwendungen ohne Probleme verwenden. Die nette Sache über MadExcept ist, dass es einen Bericht für Sie mit einem vollen Stack-Trace erzeugen, die Sie in der richtigen Richtung, die allgemein als zu werden Punkt, was schief gelaufen ist, und kann sogar einen Screenshot enthält, hat auch haben diese Sie automatisch per E-Mail von dem Kunden-Computer mit einem einfachen Mausklick.

Allerdings wollen Sie dies nicht für alle Ausnahmen verwenden, nur diejenigen zu fangen Sie vermissen. Zum Beispiel, wenn Sie eine Datenbank und die Anmeldung nicht öffnen, wäre es besser, für Sie diese ein, sich zu fangen und zu behandeln, anstatt geben dem Anwender die MadExcept Standardfehler in Ihrer Anwendung aufgetreten Nachricht.

Jede Ausnahme nicht explizit oder im Allgemeinen auf einem bestimmten Niveau behandelt wird rieselt nach oben in dem Call-Stack. (Mathematische Fehler, Zugriffsfehler, klassenspezifische Fehler etc.) - Die Delphi-RTL (Run Time Library) wird eine Reihe von verschiedenen Ausnahmeklassen erzeugen. Sie können sie gezielt gewählt oder im Allgemeinen außer Blöcke in den verschiedenen Versuch zu behandeln.

Sie brauchen nicht wirklich keine neue Ausnahmeklassen zu erklären, es sei denn, Sie einen bestimmten funktionalen Zusammenhang mit der Ausnahme propagieren müssen.

Wie schon in früheren commen schrieben, Sie können auch eine Mutter alles Exception-Handler wie MadExcept oder Eurekalog fügen Sie die abgefangene zu fangen.

Bearbeiten: Dies ist eine Decke Versicherung gegen nicht behandelte Ausnahmen

try
  ThisFunctionMayFail;
except
  // but it sure won't crash the application
  on e:exception
  do begin
    // something sensible to handle the error 
    // or perhaps log and/or display the the generic e.description message
  end
end;

Für Laufzeit versuchen Eurekalog . Ich weiß nicht, ob ein Werkzeug zur Entwurfszeit vorhanden ist. Sie werden mehr dificoulties haben, auch wenn Sie Code von Drittanbietern ohne Quelle. Es besteht keine Notwendigkeit in Delphi Ausnahmen zu fangen, so müssen Sie sie nicht erklären, wie in Java.

Was ich sagen wollte, ist, dass Delphi nicht erfordert, dass eine Ausnahme behandelt wird. Es wird nur das Programm beenden. Eurekalog stellt Mittel behandelt und nicht behandelte Ausnahmen zu protokollieren und eine Fülle von Informationen über den sate des Programms zur Verfügung stellen, wenn die Ausnahme aufgetreten, einschließlich den Codezeilen, es trat bei und dem Call-Stack an der Zeit.

Wie Jim McKeeth weist darauf hin, können Sie nicht eine definitive Antwort bekommen, aber es scheint mir, dass man kann teilweise die Frage beantworten, durch eine statische Analyse: Da eine bestimmte Funktion / Prozedur, konstruiert ein Aufrufgraphen. Überprüfen Sie jede der Funktionen in diesem Aufrufdiagramm für eine Erhöhung Aussage. Das würde Ihnen sagen, zum Beispiel, dass TIdTcpClient.ReadString eine EIdNotConnected erhöhen kann (unter anderem).

Ein kluger Analysator auch beachten könnte, dass einiger Code den / Operator verwendet und umfasst EDivByZero als eine Möglichkeit, oder dass einige Verfahren greifen auf ein Array und umfasst ERangeError.

Diese Antwort ist ein bisschen enger als einfach greppen für „heben“.

Die Finalisierung Abschnitte von Einheiten können Ausnahmen erhöhen. Diese werden verstreichen Ich denke, ... und sind auch etwas problematisch.

Ich denke, Delphi IDE hat einen eingebauten "Stack-Trace" oder "Stapel Baum" so etwas wie.

Diese Frage erinnert mich an TRussianRoulette Spiele Skybuck ... google es, es ist Code und Antwort helfen können.

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