Reputation: 12589
I work in C#, so I've posted this under C# although this may be a question that can be answered in any programming language.
Sometimes I will create a method that will do something such as log a user into a website. Often times I return a boolean from the method, but this often causes problems because a boolean return value doesn't convey any context. If an error occurs whilst logging the user in I have no way of knowing what caused the error.
Here is an example of a method that I currently use, but would like to change so that it returns more than just 0 or 1.
public bool LoginToTwitter(String username, String password)
{
// Some code to log the user in
}
The above method can only return True or False. This works well because I can just call the following:
if(http.LoginToTwitter(username, password))
{
// Logged in
} else {
// Not Logged in
}
But the problem is I have no way of knowing why the user wasn't logged in. A number of reasons could exist such as: wrong username/password combination, suspended account, account requires users attention etc. But using the following method, and logic, it isn't possible to know this.
What alternative approaches do I have?
Upvotes: 8
Views: 410
Reputation: 1993
You can use an idiom that is frequently used in c. The result of an assignment expression is the expression itself - this means you can capture a result code at the same time as evaluating whether it's a particular value:
if ((status = DoSomething()) == AnErrorEnum.NotAnError)
{//success handler
}
else
{//failure handler
}
I was asked to provide a link to an MSDN article - here is an old version of the spec: http://msdn.microsoft.com/en-us/library/aa691315(v=vs.71).aspx
"The result of a simple assignment expression is the value assigned to the left operand. The result has the same type as the left operand and is always classified as a value."
Upvotes: 0
Reputation: 34145
There are two standard ways. If you're interested in just the outcome, but not any metadata, return some enum instead. Set the available values to Success
, Suspended
, etc. (all your possible outcomes)
If you need some more details, you can always use exceptions. Basically follow the "tell, don't ask" idea and write your function in a way that it returns required values (user id for example? or maybe nothing if you have some global login state) only on success and throws an exception with detailed description of the failure otherwise. Regarding the hierarchy itself, you should most likely implement a LoginException
with some more specific subclasses and catch only those. (it makes it easy to verify all relevant exceptions are handled and all unknown ones are passed to higher levels)
Upvotes: 6
Reputation: 283634
Both returning an enum or throwing an exception, as suggested in other answers, are reasonable. But my preference is to return an exception. Sounds crazy, but it lets your caller decide whether to use error checking or exception handling. And, unlike the enum, exceptions are hierarchical, so it makes it much easier to handle entire categories of failures, and can carry arbitrary extra data.
I think Sayse had a similar idea, but he deleted his answer and never really explained it either.
Upvotes: 3
Reputation: 1863
You could create and return an enum
with expected LoginResults.
public enum LoginResult
{
Success,
AccountSuspended,
WrongUsername,
WrongPassword,
}
Then return using the enum type in your method:
public LoginResult LoginToTwitter(String username, String password)
{
// Some code to log the user in
}
Upvotes: 8
Reputation: 11250
According to clean code tendency you should provide a meaningfull name for your method that reveal intent.
For to know what happened if logging operation could no be completed you can introduce in your flow Exceptions
and handle it in the caller context.
see http://msdn.microsoft.com/en-us/library/ms173160(v=vs.80).aspx
Upvotes: 0
Reputation: 10489
You could choose to either throw an exception with a relevant message attached (and have the calling method deal with the exception), or have the function return an enum
with different states (such as LoginState.Success
, LoginState.IncorrectPassword
, etc.).
If you are using exceptions, it's probably best to have your function return nothing (public void LoginToTwitter
), but if you're using an enum
, make sure the set the return type to the name of your enum
(public LoginState LoginToTwitter
).
Upvotes: 8