6

So, we are using the Enterprise Library 4.1 Exception Handling Application Block to deal with logging/handling our exceptions in a multiple-project application. We have a few custom exceptions and are throwing some exceptions whose classes are defined in the .NET framework's standard class libraries (e.g. ArgumentException, InvalidOperationException, ArgumentNullException, etc.).

Today, our team lead decided that he didn't want us to use the latter, since the .NET framework would throw those types of exceptions, and in order to facilitate filtering with the application block's policies, we should use only custom exceptions, going so far as to practically duplicate .NET standard class library exceptions with custom versions, as in CustomArgumentException, CustomInvalidOperationException, etc.

My question is, what is wrong with this approach? I couldn't put my finger on it at the time, but it smelled wrong to me and I haven't been able to shake my uneasy feelings about it. Am I worried about something that really isn't that big of a deal? I guess it just feels like the tail wagging the dog a bit here...

Jason Bunting
  • 58,249
  • 14
  • 102
  • 93

5 Answers5

12

Ick. What I don't like about it is:

  • It duplicates existing types
  • It violates the principle of least surprise
  • It means that if you want to find everywhere you've used the wrong argument value (say) you have to look for two type hierarchies of exception instead of just looking for ArgumentException.

I would suggest you get your team lead to read item 60 of Effective Java 2nd edition. Yes, it's about Java rather than C# - but the principles remain the same.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
4

The Framework Design Guidelines book (first edition) by Krzysztof Cwalina and Brad Abrams recommend throwing existing exceptions defined in the System namespaces where you can, and the more specific the better. If there isn't a good fit then throw a custom exception.

Creating a parallel universe of CustomArgumentNullException to match System.ArgumentNullException is a duplication of effort that I don't see any value in. At the end of the day if your code throws a System.ArgumentNullException rather than a framework class you can determine from the stack trace who was ultimately responsible.

This smells of unnecessary extra work for the present and in the future when it comes to code maintenance time.

Kev
  • 118,037
  • 53
  • 300
  • 385
4

I echo the answers by Jon Skeet and Kev. I'd just add that if your exception policy wants to treat framework-level exceptions different to your own exceptions, consider using the exception's stack trace.

// Somewhere within a custom exception handler policy
var frame = new StackTrace(exception).GetFrame(0);
if (frame.GetMethod().DeclaringType.Namespace.StartsWith("MyNamespace.")) 
{
    // Handle exceptions from our code
}
else 
{
    // Handle framework-level exceptions
}
Paul Stovell
  • 32,377
  • 16
  • 80
  • 108
  • I don't like stacktrace-based approaches. If a program is supposed to parse an input file, certain types of invalid input should cause an ArgumentException which should result in a "File is not valid" message, but other things could go wrong which could disrupt the broader system state (especially if some data structures are shared among multiple open documents). It's important that the caller know whether an exception indicates a file-open failure or a corrupted system state. Using a custom exception type LoadDocumentFailure may take care of this. – supercat Apr 18 '11 at 01:22
  • This also screws you with inlining. Throwing different exceptions is much less dodgy. – Mark Sowul Jun 02 '12 at 23:23
1

Well, Exceptions thrown by your code and thrown by the .net base classes should both be handled the same way.

Both are probably the symptom of a problem in your code, so neither should be ignored, or filtered !

Brann
  • 31,689
  • 32
  • 113
  • 162
0

Throwing .Net exceptions is fine when the exception rightly describes the type of problem you're trying to expose (e.g. when an argument is null you should throw a ArgumentNullException). If you find a situation that isn't handled by the .Net framework (e.g. You want to divide 6 by 3 but that isn't allowed by your application) you should create a custom exception.

Matt Ruwe
  • 3,386
  • 6
  • 39
  • 77