I think about it roughly this way (in reverse priority): Contracts/assertions concern problems in the program(ming) domain.
Exceptions concern problems in the system domain. Problems in the actual problem domain should be modeled in the design and have their own abstractions. These interact a little bit, so I have an excuse to bend my rules whenever I want :) For instance, if the system is part of your problem domain (e.g. embedded code), then exceptions are probably not the right approach. That's why I indicate a false idea of priority. Jason