I'm running up against the age old return codes versus exceptions debate, and could do with some advice on a concrete example.
I have a simple method Authenticate, which takes your typical username, password and returns a session key on success, otherwise returns the failure reason. Something like:
Guid Authenticate(string username, string password)
Although the failure reason won't be displayed to the user I'd like to pass this up the layers so that they can take appropriate action.
I think there are three groups of possible responses:
1. Success
2. Expected/common failures e.g. invalid password/user, account locked
3. Unusual/unexpected failures/exceptions e.g. db connection failure etc
I'm happy with 1 being indicated by returning a valid guid, and 3 by an exception bubbling up, but what should I do for 2?
I'm edging towards exceptions, but I'm not sure something common like a incorrect password which could happen 50% of the time should do this? Alternatives are returning some sort of complex return status object (including the guid if successful) or an out parameter??
Try out using pattern Do()/TryDo() for better flexibility of the API. So client (class, service, etc) which uses this API would have options:
API:
// Throw in case of error with AuthenticateExceptionEventArgs
// contains information regarding error context
Guid Authenticate(string name, string password);
// Returns a status of operation, does not throw in case of error
AuthenticateStatus TryAuthenticate(string name, string password, out Guid guid);
Requires following infrastructure types:
enum AuthenticateStatus
{
Success,
InvalidPassword
}
class AuthenticateExceptionEventArgs : EventArgs
{
public AuthenticateStatus Status { get; private set; }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With