Which design is most preferable: test-create, try-create, create-catch?
<p>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. There are three approaches of doing this as I see it and I'm wondering whether there is a clear winner.</p>

<p>So, here's a class user:</p>

<pre><code>class User
{
    public string Email { get; set; }
    public string UserName { get; set; }
}
</code></pre>

<p>And there are 3 ways of accomplishing create operation:</p>

<p><strong>Test-Create</strong></p>

<pre><code>if (UserExists(user)) act on user exists error;
if (UsernameExists(user)) act on username exists error;
CreateUser(user);
</code></pre>

<p>UserExists and UsernameExists make request to db server to do a validation. These calls are again repeated in CreateUser to ensure API is used correctly. In case validation has failed, I throw ArgumentOutOfRangeException in both cases. So there is a performance hit.</p>

<p><strong>Try-Create</strong></p>

<pre><code>enum CreateUserResultCode
{
    Success,
    UserAlreadyExists,
    UsernameAlreadyExists
}

if (!TryCreate(user, out resultCode))
{
    switch(resultCode)
    {
        case UserAlreadyExists: act on user exists error;
        case UsernameAlreadyExists: act on username exists error;
    }
}
</code></pre>

<p>This pattern does the validation only once, but we resort to using the so called error codes which isn't considered a good practice.</p>

<p><strong>Create-Catch</strong></p>

<pre><code>try
{
    CreateUser(user);
}
catch(UserExistsException)
{
    act on user exists error;
}
catch(UsernameExistsException)
{
    act on username exists error;
}
</code></pre>

<p>I don't use error codes here, but I now have to create a separate exception class for every case. It's more or less how exceptions are supposed to be used, but I wonder if creating a separate exception instead of enum entry is worthwhile.</p>

<p>So, do we have a clear winner or it's more a matter of taste?</p>
