Mythos: Catch( Exception) ist böse


Thomas Wölfer
Thomas Wölfer

22. März 2005


Wer FxCop verwendet, der wird über lang oder kurz über eine Meldung stolpern: FxCop bemängelt das fangen von Exceptions der allgemeinen Exception Basisklasse:

try
{
  // hier ist der code
}
catch( Exception ex)
{
   // behandlung des problems
}

wird von FxCop also bemängelt. Und das ist generell auch gut so: Man sollte im Regelfall genau die Exceptions fangen, die man auch behandelt - und nicht einfach völlig beliebige. In sofern ist FxCop schon im Recht, und weist einen durch sein Meckern auf Stellen im Code hin, die man sich zumindest einmal ansehen sollte.

Es gibt aber Fälle, bei denen die Sache nicht ganz so klar ist. So ein Fall ist zum Beispiel Directory.CreateDirectory(). Die Methode kann 7 unterschiedliche Exceptions werfen. 6 davon sagen im wesentlichen aus 'Das erzeugen des Verzeichnisses ging nicht' - die siebte sagt aus, das der übergebene Parameter 'null' ist. Die übergabe eines Nullpointers ist sicher ein Bug im Programm - man will die zugehörige Exception also nicht fangen. Die anderen 6 aber schon.

Nun ist es so, das einige der Exceptions von einander abgeleitet sind, sodas sich Code ergibt, der bei strikter Einhaltung der FxCop Regel so aussieht:

DirectoryInfo di = null;
try
{
 di = Directory.CreateDirectory( folderName);
}
catch( IOException ex)
{
   MessageBox.Show( "directory creation failed. reason:" + ex.Message);
   return null;
}
catch( UnauthorizedAccessException ex)
{
   MessageBox.Show( "directory creation failed. reason:" + ex.Message);
   return null;
}
catch( ArgumentNullException ex)
{
   // this is a bug. rethrow.
   throw;
}
catch( ArgumentException ex)
{
   MessageBox.Show( "directory creation failed. reason:" + ex.Message);
   return null;
}
catch( NotSupportedException ex)
{
   MessageBox.Show( "directory creation failed. reason:" + ex.Message);
   return null;
}

Das ist ganz offensichtlich Blödsinn: Eine Zeile Code für den CreateDirectory() Aufruf bläht das Ding ins unendlliche auf. Der Benutzer hat obendrein keinerlei Vorteile - es bringt hier einfach nichts, alle Exceptions einzeln zu fangen.

Was also tun?

Naja - ich habe das offensichtliche getan und mich an Brad Abrams gewendet, der sollte schliesslich wissen wie die FxCop Regel gemeint ist, denn die Design-Rules sind ja nunmal auch sein Werk.

Brads Antwort kam extrem prompt: Die aktuelle FxCop Regel ist nicht so doll, und das Team denkt schon darüber nach die Regel zu entfernen.

Im Regelfall sollte man zwar wirklich nicht 'Exception' fangen - aber andererseits sollte man alle Exceptions fangen die man auch behandelt. Und die Anzeige der Meldung 'Das Verzeichnis konnte nicht angelegt werden', versehen mit dem zusätzlichen Erklärungstext aus der Exception, kann man nun wohl ganz sicher als Behandlung des Problems ansehen.

Dazu gibts netterweise sogar ein paar Slides von Brad, und eines davon behandelt exakt diese Fragestellung.