hi,
Die Exceptions in den Fällen (a) und (b) wirst du doch eher global abarbeiten. D.h. "um dein ganzes Programm rum" wirst du ein try/catch-setzen, welches die Exception fängt und dann entsprechend dein Programm sauber herunterfährt oder sowas.
Neiiiiin. Nicht global ;)
Meine DB-Zugriffe organisiere ich in Klassen, wobei ich das Ex.Model nur innerhalb der Klasse anwende, Beispiel:
sub pick{
my $self = shift;
my $cart = Cart->new(%{$self->{CFG}{mysql}}) or do{
$self->errpush("Bedaure, keine Verbindung zur DB", $@);
return;
}
$cart->pick(%article) or do{
$self->errpush("Leider schiefgegangen", $@);
return;
};
}
Zum Debuggen gebe ich außerdem $@ aus, da steht der Grund der Ex. drin, die innerhalb der Klasse Cart aufgetreten ist. Das interessiert den Kunden zwar weniger, ist jedoch für eine Ferndiagnose hilfreich ;)
Betrachte jedoch mal folgenden Hack (6 Zeilen Code gespart):
sub pick{
my $self = shift;
my $cart = Cart->new(%{$self->{CFG}{mysql}}) or die $@;
$cart->pick(%article) or die $@;
}
Unverschämt! Würde ein Fremder sagen, der Kunde bekommt einen 500er, die Anwendung stirbt ja weg!
Nein, macht sie nicht ;)
Der Code der pick()-Methode liegt in dem Moment, wo die Methode aufgerufen wird, als anonyme Code-Referenz im Haupspeicher. Aber nicht nur das: Mein Programm hat den Zugriff über $code. Wie geil: Hier wird die Ex. abgefangen.
Im Fall (c) ist deine Exception-Verarbeitung aber sehr lokal. Du willst dann nämlich genau für ein Query wissen, ob es erfolgreich war. Aber dann hast du keinerlei Vorteil gegenüber einer einfachen Überprüfung auf den Rückgabewert des Queries, der Aufwand ist gleich hoch.
Ok, zurück zu DB-Zeugs. Wie gesagt, ich organisiere in Klassen, für alles, was zu tun ist, gibts Methoden, die sehen in der letzten Zeile alle gleich aus:
return $@ ? undef : $rv;
Dabei ists egal, ob im try-Block ein oder mehrere Statements notiert sind, wenn bei einem der ST ein Fehler auftritt, steht der Grund in $@, fertig.
Bitte zeige mir noch mehr Fälle, in denen ein DB-Query nicht erfolgreich ist und nicht Fall (a) bis (c) eintritt. Und dann kann man auch (im Beispiel Exceptions durch DB) entscheiden, ob es sinnvoll oder nicht sinnvoll ist, Geschäftslogik durch Exceptions zu behandeln.
Es ist keine Schande, Programmlogik per Ex. zu entscheiden, es gibt, richtig organisiert, erhebliche Vereinfachungen gegenüber herkömmlichen Kontrollstrukturen. Es muss nur dafür gesorgt werden, dass bis zum Schluss ein stabiler Zustand besteht. Dem Anwender schließlich ists auch egal, mit welchen Mitteln die Anwendung intern arbeitet.
Wenn ich mir ein Modul von CPAN schnappe und weiß, dass ich Fehler in $@ finde, weiß ich auch, dass Modul-Intern mit Exceptions gearbeitet wird, anderweitig würde nichts in $@ stehen. Abstrakt gesehen, ists mir als Anwender eines CPAN-Moduls jedoch egal, wie das intern arbeitet, hauptsache, ich weiß, wo ich die Fehlermeldungen finde.
Hotti
--
Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.