Perl: Fangfehler ohne Würfel

8

Ich spiele mit der Fehlerbehandlung herum und habe ein kleines Problem. Ich verbinde mich mit einer Datenbank mit dem DBI-Modul.

Ich mache meine eigene Fehlerbehandlung, indem ich ein Unterprogramm verwende, das einen Fehler aufruft.

Ich kann meine eigenen Würfel fangen und sie gut behandeln, aber wenn meine Datenbankverbindung ausfällt, druckt das DBI Modul offenbar sein eigenes sterben aus:

  

DBI connect (...) fehlgeschlagen: ORA-12154: TNS: konnte die       Verbindungskennung angegeben (DBD ERROR: OCIServerAttach) bei ...

Wie würde ich das fangen?

Ich habe versucht, $SIG{__DIE__} so zu verwenden:

%Vor%

Dies ist auf der Unterseite meiner Hauptdatei, in dieser Datei rufe ich auch die Verbindungsunterroutine auf, die in einem eigenen Modul verfügbar ist. Ich habe auch versucht, dieses Stück Code auf der Unterseite meines Moduls zu setzen, aber es druckt immer noch den Fehler ohne

  

Fehler:

davor.

    
Pmarcoen 13.04.2010, 09:41
quelle

5 Antworten

3

Okay, ich fand die Lösung, anscheinend brauchte ich __WARN__ anstelle von __DIE__ und dieses Stück Code musste oben in der Datei sein, bevor der Fehler ausgelöst wurde, anders als das Beispiel, das ich gelesen habe :)

    
Pmarcoen 13.04.2010, 11:27
quelle
8
  

DBI connect (...) fehlgeschlagen: ORA-12154:   TNS: konnte die Verbindung nicht auflösen   Bezeichner angegeben (DBD FEHLER:   OCIServerAttach) bei ...

     

Wie würde ich das fangen?

Um diese Fehlerstufe zu erfassen und zu behandeln, verwenden Sie eval in Blockform "eval {...}". Dies wird jeden Würfel fangen, der im Untercode passiert. Wenn der Code in einem Eval-Block abstirbt, wird $ @ gesetzt und der Block wird false zurückgeben. Wenn der Code nicht stirbt, wird $ @ auf '' gesetzt.

Da die Signalverarbeitung über SIG {WARN} und SIG {DIE} problematisch ist, da sie global sind, müssen auch Race-Bedingungen berücksichtigt werden (was passiert, wenn ich ein Signal bekomme, während ich ein anderes Signal handle? traditionelle Probleme des Signal Based Computing). Sie schreiben wahrscheinlich Single-Threaded-Code, so dass Sie sich keine Gedanken über Nebenläufigkeitsprobleme mehrerer aufrufender Dinge machen müssen, aber der Benutzer sollte darüber nachdenken (vielleicht sendet er einen SIGKILL, während Sie versuchen, die DBI-Verbindung zu öffnen) )

In diesem speziellen Fall verwenden Sie DBI. Mit DBI können Sie steuern, was im Falle eines Fehlers geschieht, ob es abbricht, warnt oder im Hintergrund fehlschlägt und auf die Überprüfung des Rückgabestatus wartet.

Hier ist ein grundlegendes Beispiel für die Verwendung von eval {...}.

%Vor%

Es gibt einige kleinere Probleme bei der Verwendung von eval, da es sich um den globalen Bereich von $ @ handelt. Die Try :: Tiny cpan Seite hat eine großartige Erklärung. Try :: Tiny behandelt eine minimale Try / catch-Block-Einrichtung und behandelt die Lokalisierung von $ @ und die Bearbeitung der anderen Kantenfälle.

    
spazm 14.04.2010 07:11
quelle
2

Es gibt viele Schalter in DBI, wie PrintError, RaiseError, usw., die Sie einstellen können. Siehe Ссылка

    
user181548 13.04.2010 11:03
quelle
2

Fügen Sie dies in Ihren SIG{__DIE__} -Block ein:

%Vor%

Dies verhindert, dass Ihr Handler für ausnahmebasierten Code verwendet wird, der einen Würfel innerhalb eines Eval-Blocks generiert.

    
Oesor 14.04.2010 13:30
quelle
0

Dies ist nicht so allgemein wie ein gesamter Chipfänger, aber speziell für die DBI-Fehlerbehandlung haben wir tatsächlich unser eigenes Modul, das Wrapper um Datenbankaufrufe bereitstellt; und eine der Funktionalitäten des Moduls ist das Umschließen von eval (abhängig von einem Flag) um jeden DBI-Aufruf.

Dies ermöglicht uns eine benutzerdefinierte Fehlerbehandlung auf Datenzugriffsebene, z. B. Abfrageversuche, Statistiken, automatisiertes Failover und mehr - alles transparent für den Rest des Codes.

    
DVK 13.04.2010 13:47
quelle

Tags und Links