Laden...

Für jeden Fehler eine eigene Exception?

Erstellt von philatm vor 15 Jahren Letzter Beitrag vor 15 Jahren 3.254 Views
P
philatm Themenstarter:in
7 Beiträge seit 2008
vor 15 Jahren
Für jeden Fehler eine eigene Exception?

Hallo!

Ich entwickle eine Anwendung, in der ich Geschäfts- und Präsentationslogik in zwei separaten Layern halte.

Der Präsentationslayer sollte sich ja nur mit der reinen Anzeige befassen. Soll ein neues Objekt (z. B. Produk) gespeichert werden, so reicht der Präsentationslayer die Daten an den Applikationslayer weiter. Geht jetzt irgendetwas schief, würde eine entsprechende Exception geworfen werden, die durch den Präsentationslayer behandelt und dem Benutzer gezeigt wird.

Erstelle ich jetzt für jeden Fehler eine eigene Exception? Dann braucht meine Anwendung ja später hunderte benutzerdefinierte Exceptions (z.B. kein Name angegeben, zu kurzer Name, Name schon vorhanden, Benutzer nicht berechtigt und und und). Oder mache ich eine einzelne Exception und gebe dieser noch einen Fehlercode oder -text mit?

Über Tipps und Anregungen würde ich mich freuen. Gibts da Best-Practices?

Gruß
Philip

2.082 Beiträge seit 2005
vor 15 Jahren

Hallo philatm,

Erstelle ich jetzt für jeden Fehler eine eigene Exception? Auf keinen Fall. Eigene Exceptions solltest du vermeiden oder nur dann erstellen, wenn die vorgefertigten Exceptions nicht zum Fehler passen. Siehe dazu verschiedene Artikel zu Exception Design Guidelines.

Eine Methode wäre natürlich, Application.ThreadException abzufangen und selbst zu handlen. Da kannst du ja ein eigenes Fenster anzeigen lassen.

//Edit: EventNamen korrigiert

Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de

P
philatm Themenstarter:in
7 Beiträge seit 2008
vor 15 Jahren

Hi frisch,

danke für die schnelle Antwort.

Erstelle ich jetzt für jeden Fehler eine eigene Exception?
Auf keinen Fall. Eigene Exceptions solltest du vermeiden oder nur dann erstellen, wenn die vorgefertigten Exceptions nicht zum Fehler passen.

Ok, wenn ein Argument einer Funktion null ist, werfe ich dann natürlich die existierende ArgumentNullException. Aber was ist, wenn z. B. ein Name doppelt an die G-Logik gegeben wird, der nur einmal existieren darf? Oder ein noch speziellerer Fehler?

Eine Methode wäre natürlich, Application.ThreadException abzufangen und selbst zu handlen. Da kannst du ja ein eigenes Fenster anzeigen lassen.

Ich hätte das jetzt mit


try
{
    // Geschäftslogik aufrufen
}
catch (ArgumentNullException ane)
{
    // Exception behandeln
}
catch (MyOwnException moe)
{
   // Exception behandeln
}

gemacht?

Ich werde auch nochmal ein paar Sachen zum Exceptions-Handling allgemein lesen, danke für die Links!

Gruß
Philip

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo philatm,

Aber was ist, wenn z. B. ein Name doppelt an die G-Logik gegeben wird, der nur einmal existieren darf? Oder ein noch speziellerer Fehler?

Für die meisten Fehler gibt es schon passende Exceptions im Framework. Wenn wirklich mal keine passende gibt, dann musst du eben eine eigene erstellen, aber auch nur dann.

Siehe auch die Links in ExceptionBuilder-Klasse (und Tracing).

herbivore

630 Beiträge seit 2007
vor 15 Jahren

Hallo philatm,

Aber was ist, wenn z. B. ein Name doppelt an die G-Logik gegeben wird, der nur einmal existieren darf?

InvalidOperationException. Man kann ja den Grund des Fehlers dann immer noch in der Message beschreiben.

Gruss
tscherno

To understand recursion you must first understand recursion

http://www.ilja-neumann.com
C# Gruppe bei last.fm

P
philatm Themenstarter:in
7 Beiträge seit 2008
vor 15 Jahren

Hi tscherno!

Man kann ja den Grund des Fehlers dann immer noch in der Message beschreiben.

Ok. Und Anhand der Message entscheide ich dann den genauen Fehlerfall? Was ja dann auf etwas wie


try
{
    // Code, der Exception werden kann
}
catch (InvalidOperationException ioe)
{
    if (ioe.Message == "DuplicateEntry")
    {
        // Fehlermeldung anzeigen
    }
    else if (ioe.Message == "CircularReference")
    {
        // Fehlermeldung anzeigen
    }
}

hinausläuft.

Gelöschter Account
vor 15 Jahren

Aber was ist, wenn z. B. ein Name doppelt an die G-Logik gegeben wird, der nur einmal existieren darf? Oder ein noch speziellerer Fehler?

z.b. eher eine LoginException (vorrausgesetzt sowas gibt es im framework nicht) mit der nachricht:

  1. "Der angegeben User ist bereits vorhanden"
  2. "Der angegeben User wurde nicht gefunden"
  3. "Loginversuch fehlgeschlagen"
    usw.

wobei man auch exceptiontexte regionalisieren kann.
da du hierbei volle kontrolle über die exception hast, kannst du noch zusätzliche felder hinzufügen, wenn sie sinnvoll sind. aber man sollte es mit den zusätzlichen feldern nicht übertreiben.

F
10.010 Beiträge seit 2004
vor 15 Jahren

Exceptions bei der Validierung zu werfen ist auch der falsche weg.

Diese Exceptions können nämlich u.U. beim DataBinding einfach unter den Tisch fallen.
Wenn du Businessobjekte hast, dann implementiere IDataErrorInfo und
benutze dieses auch für den Fehlerfall.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo philatm,

Exceptions anhand der Meldungstexte zu unterscheiden, ist nicht sinnvoll. Wenn du wirklich eine Unterscheidung auf so feiner Ebene brauchst (was ich nicht glaube), dann verwende doch besser verschiedene Exception-Unterklassen.

herbivore

630 Beiträge seit 2007
vor 15 Jahren

Hallo,

Ok. Und Anhand der Message entscheide ich dann den genauen Fehlerfall?

Nein! Bloss nicht! Exceptions können ja auch z.B. Mehrsprachig sein. Ich bin davon ausgegangen das du den Fehler dann in der Präsentationsschicht dem Benutzer anzeigen willst.

Gruss
tscherno

To understand recursion you must first understand recursion

http://www.ilja-neumann.com
C# Gruppe bei last.fm

2.082 Beiträge seit 2005
vor 15 Jahren

Mit try/catch zu arbeiten, ist eh keine gute Lösung imo. Man sollte try/catch nur in einzelfällen verwenden (z.B. bei Transaktionen mit der DB). Eben da, wo man den Fehler nicht selbst 100%ig vermeiden kann.

Zum Exception-Handling mit Anzeige der Fehlermeldung bitte meinen ersten Post beachten.

Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de

P
philatm Themenstarter:in
7 Beiträge seit 2008
vor 15 Jahren

Mit try/catch zu arbeiten, ist eh keine gute Lösung imo. Man sollte try/catch nur in einzelfällen verwenden (z.B. bei Transaktionen mit der DB). Eben da, wo man den Fehler nicht selbst 100%ig vermeiden kann.

Hi frisch,

wie sollen denn dann Fehler zwischen dem Business-Layer und dem UI-Layer ausgetauscht werden, bzw. im UI-Layer behandelt werden, wenn nicht mit Exceptions?
Klar, die UI prüft schon auf Fehler (Validatoren), aber die können auch nicht alles abfangen. Und zusätzlich zu den Validatoren wird das Ganze nochmal im Business-Layer geprüft, falls die UI mal ausgetauscht wird (Webservice, WinForms etc).

Gruß

Philip

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo frisch,

Mit try/catch zu arbeiten, ist eh keine gute Lösung imo.

so pauschal ist das einfach falsch. Man kann und sollte try/catch überall da verwenden, wo man es braucht.

Eben da, wo man den Fehler nicht selbst 100%ig vermeiden kann.

Dann schau dir mal die Framework-Methoden an. Fast alle können Exceptions werfen. Daher ist "da, wo man den Fehler nicht selbst 100%ig vermeiden kann" im Normalfall der ganze Code.

Eine Methode wäre natürlich, Application.ThreadException abzufangen und selbst zu handlen. Da kannst du ja ein eigenes Fenster anzeigen lassen.

Der Zusammenhang zwischen der Frage und dieser deiner Antwort ist mir nicht klar. Normalerweise braucht man Application.ThreadException nicht. Zu nicht abgefangenen Ausnahmen sollte man es erst gar nicht kommen lassen.

herbivore

Gelöschter Account
vor 15 Jahren

ein fehler muss nicht zwangsläufig zu einer ausnahme führen.

5.657 Beiträge seit 2006
vor 15 Jahren

wie sollen denn dann Fehler zwischen dem Business-Layer und dem UI-Layer ausgetauscht werden, bzw. im UI-Layer behandelt werden, wenn nicht mit Exceptions?

Würde mich auch interessieren. Es gibt ja das IDataErrorInfo-Interface, das man im Business-Objekt implementieren könnte, allerdings wird dort die Fehlermeldung per String zurückgegeben, eine Exception ließe sich viel einfacher lokalisieren und vor allem (falls möglich) behandeln.

Was gibs denn noch für Möglichkeiten? Im Zweifelsfall sind es ja oft Fehlermeldungen wie "Titel darf max. 256 Zeichen beinhalten" oder sowas. Braucht es wirklich eine Exception dafür?

Christian

Weeks of programming can save you hours of planning

Gelöschter Account
vor 15 Jahren

wie gesagt muss nicht jeder fehler auch zu einer ausnahme und damit zu einer ausnahmebehandlung führen.

eine ausnahme soll auch eine ausnahme beliben. wenn man dmit rechnet, das die gui auch über 300 zeichen liefern könnte, muss man nciht gleich eine exception schmeißen. sondern evtl mit Idataerrorinfo was machen oder irgendwie anders.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo JAck30lena,

es ist nicht nur eine Frage von damit rechnen oder nicht, sondern auch eine Frage, wo der Fehler auftritt und wo er behandelt werden kann. Wenn diese Stellen (weit) auseinander Fallen, ist durch eine Exception angebracht, selbst wenn man mit dem Fehler rechnet.

Hallo MrSparkle,

das ist eine Frage wie gemacht für FZelle. Ich vermute, er wird darauf antworten, sobald er sie sieht.

herbivore

F
10.010 Beiträge seit 2004
vor 15 Jahren

Ich hatte zwar weiter oben schon meinen Senf dazugegeben, aber dann hier nochmal.

Generell gilt, das man Exceptions nur werfen sollte, wenn es eine wirkliche
Ausnahme
gibt, die sofort behandelt werden muss.
Ist dies nicht nötig, sollte es über standartisierte Verfahren der Fehlermitteilung gehen.

Wenn im Businesslayer Validierungen gemacht werden, ist es deshalb nicht sinnvoll,
die dabei gefundenen Verstösse gegen Businessrules mit einer Exception zu behandeln.

Beim DataBinding ( z.b. in einem Grid ) werden solche Exceptions auch schon mal
gerne geschluckt, weshalb die dann folgende Fehlersuche "Lustig" wird.

Und da ist z.b. das im Framewrk vorhandene Interface IDataErrorInfo
die erste Anlaufstelle, da die meisten UI-Controls damit umgehen können.

So ein ValidationError kann dann natürlich beim Speichern schon zu einer
Exception führen, da ja jetzt sofort gehandelt werden muss ist das auch OK.

Und zu den Hunderten von Exceptiontypen, wenn du in deiner SW mehr als eine
Handvoll eigene Definieren musst, dann läuft da schon einiges schief.

Die meisten Exceptions lassen sich mit den std. Typen schon ganz gut beherrschen.

P
philatm Themenstarter:in
7 Beiträge seit 2008
vor 15 Jahren

Hallo!

Vielen Dank für die vielen Beiträge und die konstruktive Diskussion. Ich werde mir das IDataErrorInfo Interface mal anschauen und das ganze Konzept nochmal überdenken. Bisher bin ich auch mit ein paar eigenen Exceptions ausgekommen, aber bevor ich weitermache und später dann feststelle, dass ich den komplett falschen Weg gegangen bin, wollte ich nochmal nachforschen.

Gruß
Philip