Laden...

Wie verwendet und erstellt man Exceptions richtig?

17 Antworten
2,913 Aufrufe
Letzter Beitrag: vor 18 Jahren
Wie verwendet und erstellt man Exceptions richtig?

hallo,

ich habe bisher wenig erfahrung mit exception würde sie aber gerne mehr einsätzen.

nun ist meine frage aus was eine eigene exception klasse bestehen sollte, was kann man da an informationen rein packen außer errorcode und eine nachricht. also mir ist klar, dass ich da alles reinpacken kann was ich will, aber was ist sinnvoll?

erstellt man sich für seine eigene klasse immer eine exception klasse oder sollte man dies eher nicht zun?

gibt es zum verwenden von exceptions gute tutorials bzw hat jemand einen link dazu?

mfg
Zebes

hab für eine klasse von mir auch ne Exception gemacht


public class WatcherException : ApplicationException
    {
        public WatcherException()
            : base()
        { }
        public WatcherException(string strExceptionText)
            : base(strExceptionText)
        { }
        public WatcherException(string strExceptionText, Exception e)
            : base(strExceptionText, e)
        { }
    }

kannst auch beliebig erweitern....

edit:

Anwendung sollte sich von slebst erklären:


try
{
//versuche was
}
catch(WatcherException ex)
{
  throw new WatcherException(ex.Message);
}
//oder
try
{
//versuche was
}
catch(WatcherException)
{
  throw new WatcherException("Fehler aufgetreten");
}
// oder du fängst das ganze in einer MessageBox ab
try
{
//versuche was
}
catch(WatcherException ex)
{
  MessageBox.Show(ex.Message,"Fehler aufgetreten !"MessageBoxButton.OK,MessageBoxIcon.Error);
}

ich hoffe das hat dir bissl weitergeholfen

erstellt man sich für seine eigene klasse immer eine exception klasse oder sollte man dies eher nicht zun?

das macht insofern sinn, wenn du einen speziellen Fehler auch gesondert behandeln willst. also wenn du zu einem bestimmten Fehler x auch den bestimmten Fehlertext y ausgeben willst etc..

greetz..

I cna tpye 300 wrods pre mnuite!

also erst mal danke für die antworten aber meine frage bezog sich eher auf das konzept von exceptionhandling. mir ist schon klar wie ich eigene exceptionklassen schreiben kann nur halt bei der verwendung bin ich nicht ganz auf dem laufenden. mit "verwendung" meine ich jetzt auch nicht try catch blöcke sondern halt das konzept hinter exceptions.

mfg
Zebes

Hallo Zebes,

kannst du bitte noch konkreter schreiben, was du wissen willst.

herbivore

Deine Frage ist so allgemein und vor allem WICHTIG, dass ich sie auf keien Fall alleine beantworten kann. Aber ich Versuch mal mein Bestes:

**1) Als erstes muss man bestimmen, wann man eine Exception wirf. **
Ich finde, man soll immer dann eine Exception werfen, wenn der erkannte fehlerhafte Zustand/Ablauf nicht mehr in der aktuellen Methode korigiert werden kann.


public class Dimension
{
  private decimal? länge = null;
  private decimal? breite = null;
  private decimal? höhe = null;

  public decimal? Länge
  {
    get
    {
      return this.länge;
    }
    set
    {
      this.länge = value;
    }
  }

// und so weiter

  pulic decimal Volumen
  {
    get
    {
      if(länge==null||höhe==null||breite==null)
        throw new ArgumentNullException();
      return länge.Value*breite.Value*länge.Value;
    }
  }
}

2) Muss man entscheiden, wo man Exceptions abfängt.
Meiner Meinung nach, sollte man Exceptions nur dort Abfangen, wo man das mögliche Fehlverhalten auch korigieren kann


public static class User
{
  public static decimal SicheresVolumen(Dimension d)
  {
    decimal volumen = 0;
    try
    {
      volumen = d.Volumen;
    }
    catch(ArgumentNullException)
    {
      if(d.Länge==null) d.Länge=0;
      if(d.Breite==null) d.Breite=0;
      if(d.Höhe==null) d.Höhe=0;
      volumen = SicheresVolumen(d);
    }
    return volumen;
  }
}

ODER wo man eine allgemeine Excpetion mit besseren Informationen ausstatten kann.


public static class User
{
  public static T[] GetAllElementsFromIndex<T>(T[][] source, int index)
  {
    T[] re = new T[source.Length];
    for(int i=0;i<sourche.Length;i++)
    {
      try
      {
        re[i]=source[i][index];
      }
      catch(IndexOutOfRangeException ex)
      {
        throw new IndexOutOfRangeException
        (
          "Der Index " + index + " war auserhalb des Arraybereis des " + (i+1) + ".Array.",
          ex
        ); 
      }
    }
    return re;
  }
}

3) Zusätzlich ist noch der Exception Typ sehr entscheidend!
Mann muss immer abwägen:

  • Ist der Fehler so speziefisch, dass er eineb eigenen Excpetion-Typ hat.
  • Giebt es schon einen Excpetion-Typ, der zur Art dieses Fehlers passt?
  • Welchen Basis Exception-Typ könnte man nehmen, um einen Fehler-Typ weiter zu spezifizieren. (z.B. ArgumentNullExcption erweitere ArgumentExcpetion)

die frage ist eigentlich, wie ein vernünftiges exception konzept für eine software aussehen soll. klar ist, dass sie je nach applikation anders aussieht. aber es gibt doch sicherlich grundlegende vorgehensweisen für das aufbauen von exception klassen.

also als beispiel bin ich in meiner applikation hingegangen und habe eine basisklasse. zu dieser basisklasse gibt es eine exception klasse. nun habe ich für jede abgeleitete klasse eine weitere exception klasse hinzugefügt die wiederum von der basisklasseexception klasse abgeleitet ist (ich hoffe das ist jetzt nicht zu verwirrend). letztendlich beinhaltet die abgeleitete exceptionklasse meistens die gleichen daten wie die basisklasse nur das ich jetzt den typ unterscheiden kann.

würde man das so machen? oder wie konzipiert man das im allgemeinen?

mfg
Zebes

danke JuyJuka das hilft mir schon mal ein wenig weiter.

mfg
Zebes

Hallo Zebes,

also als beispiel bin ich in meiner applikation hingegangen und habe eine basisklasse. zu dieser basisklasse gibt es eine exception klasse. nun habe ich für jede abgeleitete klasse eine weitere exception klasse hinzugefügt die wiederum von der basisklasseexception klasse abgeleitet ist

das ist keine gute Idee. Exceptions stehen für Ausnahmesituationen. Es gibt keine 1:1 Beziehung zwischen einer Klasse und den möglichen Ausnahmesituationen, die bei der Benutzung der Klasse auftreten können.

Typischerweise, gibt es mehr als eine Ausnahme, die pro Klasse auftreten kann. Andererseits ist es oft so, dass bei verschiedenen Klassen die gleichen Ausnahmen möglich sind, z.B. ArgumentNullException.

Schau dir die Klassen und Exceptions im Framework an. Da gibt es so eine 1:1 Beziehung auch nicht.

Insbesondere die Exceptionklassen des Frameworks geben doch ein sehr gute Vorlage für eigene Exception-Klassen.

Exception-Klassen sollten auch nur voneinander erben, wenn die neue Ausnahme ein Spezialisierung einer bestehenden Ausnahme ist.

herbivore

naja zu zb der socket klasse gibt es einen socketexception klasse. also hin und wieder hat man eine 1:1 beziehung.

aber generell hört sich das schon mal gut an was du sagst und so ähnlich habe ich es auch an anderer stelle eingebaut.

mfg
Zebes

Hallo Zebes,

nein, es ist auch bei Socket-Exception nicht 1:1. In der Doku steht:

Eine SocketException-Ausnahme wird von der Socket-Klasse und der Dns-Klasse ausgelöst, wenn ein Fehler mit dem Netzwerk auftritt.

Und indirekt kommen noch weitere Klassen dazu. So kann auch die TcpClient-Klasse SocketExceptions werfen.

herbivore

ok das verstehe ich soweit.

danke für die antworten.

mfg
Zebes

Wenn ich für eine neue Ausnahme eine neue Ausnahmen Klasse erstelle habe ich dann nicht irgend wann das problem, das ich einfach zu viele Ausnahmen behandeln muss?

Solange mein projekt nur aus 2-3 Komponenten besteht geht es ja noch. aber mal angenommen, dass Ganze ist schon etwas größer, und an der obersten Stelle, zb im Userinterface, wird nun eine Nachricht an die unterste Schicht geschickt. Auf dem Weg dahin können nun eine ganze Menge Ausnahmen entstehen die aber unter Umständen nur durch den Benutzer im Userinterface behandelt werden können.

Was macht man nun um riesen try catch Blöcke zu vermeiden? einfach den abstrakteren exceptiontyp abfangen? oder doch 10 mal einen catch block mit den möglichen Exception Typen schreiben?

mfg
Zebes

Hallo Zebes,

einfach den abstrakteren exceptiontyp abfangen? oder doch 10 mal einen catch block mit den möglichen Exception Typen schreiben?

kommt darauf an, ob du die verschiedenen Exceptions unterschiedlich behandeln willst oder musst. Wenn du sie eh nur anzeigen willst, dann reicht auch catch (Exception).

herbivore

Grundsätzlich ist das Erstellen von Exception-Basisklassen sinnvoll. Die Frage ist nur, welcher Logik diese Vererbung folgen soll.

Man fängt ja Exceptions an Trennlinien innerhalb der Applikation. Eine Trennlinie ist üblicherweise ein Modul (Klasse) oder eine Komponente (Assembly, bzw. Namespace).

Gemäß der Architektur baut sich dann auch die Exception-Vererbungshierarchie auf.

So macht es .NET auch: So sind alle Exceptions von ADO.NET von DbException abgeleitet.

ich hätte jetzt gedacht man fängt exceptions da wo man sie behandeln will/kann

mfg
Zebes

Hallo Zebes,

tut man ja auch. Aber von fangen/behandeln hat sevenson auch gar nichts geschrieben. Er hat geschrieben, wo und wie man Exception-Klassen definiert.

herbivore