“According to the .NET Framework Class Library Design Guidelines
Exceptions are the
standard mechanism for reporting errors. Applications and libraries
should not use return codes to communicate errors. The use of exceptions
adds to a consistent framework design and allows error reporting from
members, such as constructors,that cannot have a return type.
Exceptions also allow programs to handle the error or terminate as
appropriate. The default behaviour is to terminate an application if it
does not handle a thrown exception.”
1. Does the client have access to account A?
2. Does the client have access to account B?
3. Are there enough funds in account A?
4. Is account A open?
…etc
The Microsoft recommended route seems to be to create an exception for every rules. So you’d end up with something like;
1. AccountFailedAccessException(arg)
3. AccountInsufficientFundsException
4. AccountClosedException
etc
To catch these exceptions you need to write a specific catch statement for every type of exception. This is fine if you actually want to respond to each exception in a specific way but lets say the client is only interested in, "did it fail an access check" or "some other non access problem". This is a depressingly annoying to implement since you have to catch each exception and repeat handling code, e.g.
catch(AccountFailedAccessException)
DisplayAccessNotification()
catch(AccountInsufficientFundsException)
DisplayTransferUnavailabeNotification()
catch(AccountClosedException)
DisplayTransferUnavailabeNotification()
…etc
If this was an old style error code then a switch statement would easily consume similar codes…
switch(errorCode)
case: AccountFailedAccess
DisplayAccessNotification()
case: AccountInsufficientFundsException
case:AccountClosedException
case: etc
DisplayTransferUnavailabeNotification()
Now I’ve now become convinced that exceptions are the way to go (for none performance critical) errors. The obvious solution to the above problem is to create a hierarchy of exceptions…
AccountException
AccountFailedAccessException
AccountNonAccessException
AccountInsufficientFundsExceptions
AccountClosedException
Therefore if you’re only interested in something going wrong with the Account component you’d catch nothing but the root exception of AccoundException. If you want any other exception apart from Access then you’d catch AccountNonAccessException, etc. Although this sounds good I do concede that it is still a pain to code all those exceptions.
What happens if performance is still and issue? If there is no getting away from performance then the answer is to return a state structure/class or an enum. However, the big problem with this approach is the client isn’t required to consume return code. The great thing about an exception is its in the hands of the OS, if you choose to ignore the exception then the program counter will be whipped away from you. So isn’t an easy choice for the performance freaks but I feel the tide of change is such that if you do go the error code route then fewer clients will like you for it, and in the world of SOA it is becoming harder to ignore that unknown client. I just hope I didn’t dream about the change to SEH (Structure Exception Handling) and that a new performance oriented version is around the corner.