I'm coming from a Java background, but my response should apply to .Net, as well.
Rules of thumb:
- Write your code to fail fast: Hunt & Thomas; Tip 33
- Test all of your parameters with a param check library - these are not exceptional conditions. They are misuse of the (documented) API. Example: google collections Predicates
- Use Exceptions for exceptional conditions: [Hunt & Thomas]; Tip 34. Exceptions should NOT be used as return codes.
- Test for exceptional conditions: Exceptions are postconditions for method invokations. If you can't get there with a test, the Exception shouldn't be declared.
- (For Java) Follow Josh Bloch's advice (all of Chapter 9).
Some important tips:
5a. Throw exceptions appropriate to the abstraction.
5b. Strive for failure atomicity.
5c. Include failure-capture information in the detail message (or encapsulate it in the Exception itself).
5d. Don't ignore Exceptions.