3

I've started playing with Code Contracts for .NET.

  1. I have installed the msi.
  2. In my sample Console application, in project properties, I have set "Assembly Molde" to "Standard Contract Requires".
  3. I have checked "Perform Runtime Contract Checking" to "Full".

Having this settings, I'm using the very standard Contract.Require() in my code. I cannot put it in a try block, because it should be placed on the very top of the method's body. So, my question is how I handle the exceptions that it may throw, when the "Require()" condition is not satisfied?

With correct input, my code runs well, with the intended bad input, it throws an unhanded exception. I think I'm missing some pieces in the big picture here, or maybe my project's contract options are not set well.

Thanks for your help.

Siavash Mortazavi
  • 1,382
  • 1
  • 14
  • 18
  • 2
    Why would you catch precondition failures? You 'handle' such errors by not violating the condition in the first place. – Lee Jul 18 '16 at 16:06
  • The caller should care about handling of exceptions of callee. Providing the valide input values is responsibility of caller. – Hamlet Hakobyan Jul 18 '16 at 16:11
  • @Lee Thanks, again maybe I'm missing something here, but I cannot control my code's clients. Imagine I've created a class library and a third party client makes call to my method with wrong arguments that violates my Contract.Require() conditions. – Siavash Mortazavi Jul 18 '16 at 16:11
  • @HamletHakobyan Thanks. Do you mean like the client code should wraps calls to my method in try/catch blocks and handle the exceptions there? If yes, is this generally a good pattern? I usually handle exceptions in the same scope that it happens and I don't send them up the stack. – Siavash Mortazavi Jul 18 '16 at 16:15
  • You can't handle a contract failure exception. Fixing it requires modifying code, your catch clause can not do this. Just make sure it is reported well so you know what to do, subscribe the AppDomain.CurrentDomain.UnhandledException event. – Hans Passant Jul 18 '16 at 17:19
  • Without code contracts, there is ambiguity about what constitutes "valid" input and who should be responsible to handle "invalid" values. With code contracts you make it clear and obvious that the caller is responsible for providing valid values (and handle possible invalid input). The goal is for everyone to write code where calling a method with invalid input does never happen. – Corak Jul 18 '16 at 17:19
  • @Corak Thanks, I think your comment explains the pattern very well. – Siavash Mortazavi Jul 18 '16 at 18:15
  • See also http://stackoverflow.com/questions/2639960/how-come-you-cannot-catch-code-contract-exceptions?rq=1 – Eric Lippert Jul 18 '16 at 18:47

1 Answers1

7

So, my question is how I handle the exceptions that it may throw, when the "Require()" condition is not satisfied?

You never handle that exception in production code because that exception is never thrown in a correct program. The exception exists to tell the caller that they're doing it wrong and they cannot ship their code to customers until it is fixed. If the exception is never thrown then there is never any need to handle it.

In test code, you do whatever your test framework does to represent "I expect this code to throw the following exception under the following error conditions".

Now, these facts imply something about the design of your code which uses code contracts, namely, there must be a way for the caller to know that they're not going to violate the contract without trying it and catching the failure.

I call exceptions thrown by badly-designed programs which require the caller to handle the failure "vexing exceptions". That is, you should never design a program like this:

private Phase PhaseOfMoon() { ... }
public void M()
{
  Contract.Requires(this.PhaseOfMoon() != Phase.Full);

See, the caller has no way of knowing what your private method is going to do, so the caller must catch the exception. You need to make sure that the caller always has a way to guarantee that the exception will not be thrown or the Require precondition will not be violated.

In short: your responsibility is to give them a way to avoid the exception; their responsibility is to avoid it. No one's responsibility is to handle it.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Thank you very much for the explanation. I have one more quick question please: Are Code Contracts just useful when they're used in conjunction with unit tests, or I can use them separately for the sake of code clarity and forcing an exception handling policy? – Siavash Mortazavi Jul 28 '16 at 19:30
  • @SiavashMortazavi: Code contracts and unit tests are very different things, and you can use them together or separately as you see fit. Code contracts describe and enforce preconditions and postconditions; unit tests verify correctness. – Eric Lippert Jul 28 '16 at 19:37