Let\'s assume there is an operation that creates a user. This operation may fail if specified email or username exists. If it has failed, it is required to know exactly why. The
So, do we have a clear winner or it's more a matter of taste?
The first option has a fundamental flaw - it's never going to be thread safe or safe if CreateUser
relies on external resources, and other implementations may create in between your tests. In general, I tend to avoid this "pattern" because of this.
As for the other two options - it really comes down to whether the failure is expected to happen. If CreateUser
would be expected to fail on a somewhat normal basis, the Try* pattern is my preference, as using exceptions essentially becomes using exceptions for control flow.
If the failure would truly be an exceptional case, then exceptions would be more understandable.