views:

222

answers:

2

Hi,

I'm decorating my C# code with comments so I can produce HTML help files.

I often declare and document interfaces. But classes implementing those interfaces can throw specific exceptions depending on the implementation.

Sometimes, the client is only aware of the interfaces he's using. Should I document my interfaces by adding the possible exceptions that could be thrown by its implementors?

Should I create/document custom exceptions so that interfaces implementors throw these instead of those of the framework?

I hope this is clear!

Thanks

EDIT jan 4th 2010: I decided to write a blog post about this and custom exceptions in .NET at http://blog.mikecouturier.com/2010/01/creating-custom-exceptions-in-net-right.html

+6  A: 

I am not sure I fully understood your question (and I'm a Java, not C# developer), but it seems you are asking about what is essentially an issue of polymorphism: if somebody uses a method on an interface that is declared to throw X and Y, what happens if an implementation throws Z?

One thing to follow is the principle of conformance, that essentially says that a subtype should conform to the behavior of the supertype. That is, if you are documenting that your method in the interface can only throw exceptions of one type (e.g., null pointer exceptions), then your contract with callers is that this is the only thing they should watch for. If you throw something else, you could be surprising them.

Documenting things about a specific subtype in the supertype not a good idea since it creates needless coupling. I would be more concerned about the fact that an implementation may behave differently than the declaration since that might suggest the declaration is not fleshed out enough.

Try to think what are all the types of exceptions that your method could throw. Create supertypes for them, and then explicitly declare in your interface method (e.g., this method can throw some "calculation exception"). Then, in your implementation, throw a calculation exception with more details, or throw some subtype of the calculation exception that is specific to the implementation, you would still conform.

Uri
good answer. Just what I was going to say.
Preet Sangha
Great you nailed it. I will create custom exceptions so that subtypes will throw them. I will make things general enough so that if the subtypes can't read a response in XML or in JSON (depending of the implementation), they will be able to throw a ParseException for example (and not a XmlException for the former). Thanks!
Mike Gleason jr Couturier
+3  A: 

I agree with everything Uri says - you should where sensible create custom exceptions that can be extended if required then a method which uses a parameter typed to your interface can catch that exception and it will catch subtyped exceptions as well.

Don't create them needlessly though, if there's an existing .Net Framework exception that describes your error condition use that

In terms of documenting for implementers you can use the remarks section of the comments (assuming you're using XML comments) to describe things like how you'd expect implementors to do things. Obviously this is in no way enforceable but it can serve as useful guidelines when a developer comes to use your API

RobV
Yes I try to cover everything the implementors should look for in a remarks section! You're also right on trying to use the existing exceptions as much as possible. Thanks for your help
Mike Gleason jr Couturier
also +1 for the add of details
Mike Gleason jr Couturier
I agree with Rob. I would also say that in my experience, too many exception subtypes don't really add much. Most people would prefer an exception object that is initialized with more meaningful state data, even a better error message. I use typed exceptions if I want to clarify I expect someone to recover from certain errors.
Uri
ok you're saying that I could have only one custom exception but having a member variable explaining in depth what happened? Like `throw new MyLibraryException(eReason.ParseError);` where eReason being an enum of multiple things that can happen? (it also could be a string as you said). Nice.
Mike Gleason jr Couturier
You need a good reason to create a new exception class. Unless you expect somebody to actually catch it, adding your own exception class (instead of using InvalidOperationException, ArgumentException, etc) will just decrease the solubility of your code.
Alun Harford
I agree there's plenty of things that could be an invalid operation but should I always rely on the exception's description for my implementors to discriminate the actual errors?
Mike Gleason jr Couturier
Ok I re-read your comment, yes in this case I expect somebody to pay attention of what can happen! Because 1) the function can crash in so many different stages and 2) the problem can be solved by using a wide range of libraries, technologies and techniques. You mix that together you have n * m possibilities. That's why I think a custom exception makes sense with an enumeration of which step of the function failed... like for example "UnableToAcquireData" when you try to read from a file, a socket, a web server, a user input, etc... depending of the implementation. What do you think?
Mike Gleason jr Couturier