Richtiges werfen von Exceptions


Thomas Wölfer
Thomas Wölfer

14. April 2004


Vorweg: Beim nächsten mal wird es hier wieder etwas Bauingenieurs-lastiger werden; zumindest etwas weniger aus der Programmier-Ecke. Aber eben erst beim nächsten mal. :-)

Wenn Sie einen RSS-Reader verwenden, und sich für den Programmier-Kram nicht interessieren: Abonnieren Sie einfach nicht den kompletten Feed, sondern nur die Kategorien die Sie interessieren. (Die RSS-URLs der Kategorien dazu stehen rechts am Rand.)

Zu den Exceptions:

ICommand cmd = CommandManager.GetCommand( idCommand);

try
{
   UndoManager.BeginCollection("FooBarCommand");

   cmd.Execute( context);

}
catch( Exception ex)
{
   UndoManager.ForgetCollection();
   throw ex;
}
UndoManager.EndCollection();

Dieser Code - es geht im Wesentlichen um das 'throw ex' - ist eigentlich immer falsch.

Der Punkt dabei ist der: Durch das 'throw ex' landet der eigene Stack-Trace im Exception-Object, die Original-Information geht verloren. Eigentlich muss man statt dessen einen von zwei anderen Wegen gehen.

1. Es ist wichtig das man selbst im Stack-Trace der Exception auftaucht. M.a.w.: Man ist ein relevanter Teil der Exception-Chain.

In diesem Fall sollte man die Exception in eine eigene Exception verpacken und die Original-Exception in der InnerException der neuen Exception aufbewahren. Dadurch wird die Exception spezieller und gleichzeitig bleibt die Origial-Information (in der InnerException) erhalten:

catch( Exception ex)
{
   throw new MySpecialException( ex);
}

2. Man hat die Exception nur gefangen um aufräumen zu können, man ist aber kein wichtiger Teil der Exception-Chain. (So wie im Beispiel am Anfang.)

In diesem Fall sollte man eben aufräumen was es aufzuräumen gibt, und dann die unverönderte Exception - mit ihrem Original-Stacktrace - erneut werfen:

catch( Exception)
{
   UndoManager.ForgetCollection();
   throw;  // <- kein 'ex' !
}

Dank an Brad Wilson