I'm writing a login class in c#, and I'm trying to be diligent about throwing exceptions for null passwords, insufficiant password characters, etc. The thing that suddenly occured to me was - What do I do with these exception? What/who are they for? Whether I handle the exception or not, the app will still fail at that point. Is the exception for other developers, the customer!?
-
1possible duplicate of [Exceptions or error codes](http://stackoverflow.com/questions/253314/exceptions-or-error-codes) – Joel Etherton Dec 14 '10 at 18:03
-
5I don't see this as a duplicate. This question is 'why do it?' while that question is 'how should I do it?' It's very similar though. – jcollum Dec 14 '10 at 18:24
11 Answers
If you're the one creating the Exception, you shouldn't do anything with it.
Exceptions are your way of letting your consumers know that something went wrong that you can't properly recover from. You're giving them the chance to either correct the issue, log the error, or pass the Exception up the chain until something useful can be done with it.

- 242,243
- 40
- 408
- 536
-
2That's a weird way to put it. At lot of people end up writing both the classes and the clients! – André Caron Dec 14 '10 at 18:04
-
6@André Caron While that is true, you need to be able to change hats. When you are writing a method then you are not the client of the method. Later when you write the client code then you do not need to worry about the details of the method, only the contract. – Vincent Ramdhanie Dec 14 '10 at 18:08
-
Does this mean then, that exceptions are typically thrown at lower levels but should be managed in such a way further up the chain, that the application should continue to function? – hoakey Dec 14 '10 at 18:16
-
@hoakey - If you can gracefully recover from the Exception, then chances are it should be logged somewhere but the app can continue to function. Some Exceptions can't be recovered from and cause the app to stop. – Justin Niessner Dec 14 '10 at 18:21
-
1@Vincent: yes, I totally agree, but the first sentence, taken by itself is just plain weird! – André Caron Dec 14 '10 at 18:21
-
@hoakey: that's the idea. The point is that code that *detects* the error and code that *handles* the error are rarely in the same method. And yes, the code that handles the error is usually higher up the chain. – André Caron Dec 14 '10 at 18:22
-
@Andre - I re-worded the first sentence to hopefully be a little less "weird". – Justin Niessner Dec 14 '10 at 18:24
-
I think there are situations where a method would want to react to a particular exception. They are not the norm though. I think this is the reason that we have typed exceptions instead of just one generic exception class. – jcollum Dec 14 '10 at 18:26
-
@jcollum - The OP was specifically asking about situations where he was creating the Exception. If he could react to it properly himself, he wouldn't need to create and throw a new Exception in the first place. – Justin Niessner Dec 14 '10 at 18:27
Exceptions are used to provide detailed information about the cause of a particular failure. If you simply let the code fail on its own you miss the opportunity to provide richer details about the actual cause of the failure.
Your users should not be seeing the information you add to your exceptions. Instead, consider adding a global exception handler that catches your detailed exceptions, logs the information, and then displays a friendly error message to your user.
Exceptions provide not only a detailed message in your logs about why the failure occurred (i.e. password was null in your example) but also call stack information that indicates the call chain that led to the exception. In a login form this is less important. However, in a multi-threaded asynchronous client/server application this can be critical.
This article contains many good guidelines: http://msdn.microsoft.com/en-us/library/ms229005.aspx

- 1,839
- 2
- 15
- 17
To signal to the next level up of abstraction that there is a problem, and alter its logical flow to account for the problem.

- 6,255
- 8
- 45
- 71
The exception itself happens to prevent bigger problems in the future. If you just silently did nothing when you knew something happened that wasn't supposed to, the program calling your code might assume that the user's file got saved when it really didn't, which can obviously be worse than if it's able to tell the user, "I couldn't save your file."
The message you give to an exception is for other developers. If the program crashes during development, the developer should be able to see the stack trace and more easily figure out why something happened that wasn't supposed to. Ideally you'll be able to log errors in such a way that developers can see them even in production.

- 151,543
- 27
- 246
- 315
-
I personally prefer `On Error Resume Next`... I can't even say it without shuddering. There were some symptoms to bugs I had to fix that were the real world equivalent of miles from originator of the bug. – ChaosPandion Dec 14 '10 at 19:45
-
Exceptions usually indicate that the contract of the method has been violated. The client of the method cares about the exception and should handle them appropriately. When the contract is violated, the method itself usually cannot recover and cannot produce meaningful results. The exception indicates that no meaningful results is forthcoming.

- 102,349
- 23
- 137
- 192
-
+1: this is probably the most sensible rule about exception handling I've ever heard. However, there are security issues related to plain error codes in a login context. – André Caron Dec 14 '10 at 18:17
In short, the point is to indicate that something which shouldn't have happened did indeed happen.

- 44,917
- 17
- 105
- 161
-
I hear this very often in error code VS exception discussions and it has never, even once, seemed like a good argument. "Shouldn't have happened" is subject to debate. – André Caron Dec 14 '10 at 18:20
-
Exceptions are expensive to throw and handle--a well designed system will validate that conditions are met before performing an action which could produce an exception. That's not to say that Exceptions should never occur--but they should be reserved for cases where things are either done incorrectly or when an unexpected condition occurs. – STW Dec 14 '10 at 18:22
-
STW@ in that case, you would possible not throw an exception for a null password, as this is isn't a failure as such? – hoakey Dec 14 '10 at 18:25
-
@hoakey -- the method validates a password; so if no password is given you could return false (implying "that's not valid") or throw an ArgumentNullException (implying "you didn't give me a password to validate"). I would lean towards the latter; it's not the validator's job to ensure the user input a required field, so throwing an exception is perfectly fine. However, returning `false` wouldn't be incorrect either. – STW Dec 14 '10 at 18:38
-
@STW - I'm slowly discovering with programming that it's possible to spend too much time over-think alternative approaches, and not get on with the job of coding. – hoakey Dec 14 '10 at 18:42
-
@hoakey -- definately not just you. It's a critical skill for a developer to be able to think through different approaches and weigh the pros/cons of each. There are no silver-bullets in engineering; doing something the same way all the time almost guarantees that you're doing it incorrectly *some* of the time. – STW Dec 14 '10 at 18:46
Exceptions are a way for code to notify callers of some kind of failure. The calling code can do whatever they want with it, like display an error message, suppress the exception and degrade gracefully, etc.

- 51,091
- 10
- 150
- 143
So. you've written an excellent program. this program has a possible fail point. if for whatever reason the part of the program fails you might still want to continue the rest of the program and either call explicit attention to failure, log it, or just keep on going.
I'm going to use a pseudo-code syntax, but you should be able to follow it:
var pw=$_POST['pw'];
var un=$_POST['un'];
try{
$sql="select lastlogin,access from users where un=q(/'$un'/) and pw= q(/'md5($pw)'/)";
$user=$db->getRow($sql);
if(!$user) {
//they don't exist
}else{
//process their login
}
}catch(Exception $e){
//we has a Database error. either my query s really screwed up or the DB is down. let's log it and exit this stream; service
$mylogger->log("Error while logging in using module $MODULENAME$ ".implode("<br/>",(array)$e));
exit;
}

- 7,133
- 1
- 21
- 27
-
yeah well, I did no debugging... and not sure about my q(/''/) syntax. Think you can do that in oracle now but seem to have forgotten for sure. – FatherStorm Dec 14 '10 at 18:39
If your function will throw an exception if it can't log in, then code which calls your function can assume that if your function returns, it's logged in. This will ease the amount of work the code has to do to handle the "login succeeded" scenario, in exchange for requiring more work in the "login failed" scenario. If code will sometimes be used in cases where failure is semi-expected (e.g. try logging in with one set of credentials; if that doesn't work, try some other set) and sometimes used when failure would be unexpected and unrecoverable, it may be helpful to either have a "throw on error" boolean flag, or else have separate "Login" and "TryLogin" methods.

- 77,689
- 9
- 166
- 211
The nature of exceptions is that they have to be explicitly ignored. Suppose you have this function:
bool authenticate ( String username, String password )
{
if ( invalid_password(password) ) {
return (false);
}
// ... perform authentication ...
}
Now, consider that this is part of some server, and that the server runs in a highly privileged context. If the calling code (the one that performs authorization) has some error in it's logic, it might unintentionally allow users to perform actions they are not normally allowed.
I would write the following function instead:
void authenticate ( String username, String password )
{
if ( invalid_password(password) ) {
throw new LoginFailed();
}
// ... perform authentication ...
}
Note that this is purely a defensive programming approach, and it is my preference within this context. This way, an error in login will most likely not allow the operation to keep executing.

- 44,541
- 12
- 67
- 125
-
...had to think about this more, and this smells. While it's clever, it makes this code harder to consumer. How does another developer know this method throws an exception instead of returning false (as the signature implies it will)? – STW Dec 14 '10 at 18:31
-
in this context it would be better to have the method defined as `void authenticate()` -- a function which always returns `true` (or throws an exception) reeks of code-smell. – STW Dec 14 '10 at 18:36
-
@STW: How does another developer know? By reading the documentation for the API, of course. This is obviously only a glimpse at what the code would do with emphasis on the exception VS error code. – André Caron Dec 14 '10 at 19:05
-
@STW: It does not "always return `true` or throw an exception". It raises an exception on failed login and returns nothing on success. Care to explain what *reeks*? – André Caron Dec 14 '10 at 19:07
-
@Andre "returns nothing on success" -- that's impossible in C# given a method signature of `bool authenticate()`, unless you throw a `LoginSucceeded` exception in place of `return true`. =P – STW Dec 14 '10 at 19:13
-
4Invalid credentials when trying to authenticate is not exceptional - I think returning `LoginResult` or similar would be much clearer to the client. – Lee Dec 14 '10 at 19:16
-
1@STW: that is why he changed the signature in the second example to `void`. I agree with Lee, though, that an invalid password is not an exception in programming terms. It happens all the time, and should be part of your normal logic flow. However, if a particular method should never be called unless the user is authenticated, that method should have a guard clause that throws an exception if the user is not authenticated. – StriplingWarrior Dec 14 '10 at 20:07
-
@STW: you obviously can't read. The signature clearly shows `void authenticate(...)`, not `bool authenticate(...)`. – André Caron Dec 14 '10 at 20:41
-
@Lee: care to define what is and is not *exceptional*? As the beginning of my post states, exceptions define control flow, not *exceptional conditions*. They have the significant advantage (over status codes) of *not being ignored by default*. This power can be an important tool in any context where you don't trust the caller to check the return value. This, btw, is why `new` throws `std::bad_alloc` instead of a null pointer when it can't allocate memory. – André Caron Dec 14 '10 at 20:47
-
@Lee: as far as I'm concerned, running out of memory is not an exceptional condition. I frequently work with datasets (up to 2TB) that don't fit into memory and I don't find `bad_alloc` to be particularly exceptional. – André Caron Dec 14 '10 at 20:51
-
1@André - I'd say an exceptional condition is one that cannot be either expected or protected against (or both). Opening a file that doesn't exist is exceptional since there's no way to know if it will succeed without trying it. It's reasonable to throw exceptions for contract violations since a method cannot protect against bad arguments. However in your example invalid credentials are not bad arguments (since preconditions are static) and they can be expected since failed logins are common. Handling this case should be part of the normal control flow of the application. – Lee Dec 14 '10 at 21:35
-
I'd agree that it would be reasonable to throw an exception if an attempt was made to access a protected resource with invalid credentials however, since the client could reasonably be expected to know if the operation should succeed beforehand. – Lee Dec 14 '10 at 21:37
-
@Lee: the file case depends on your application. Not finding a primary configuration (e.g. `/etc/apache2/httpd.conf`) might be exceptional, but not fining a user customization file (e.g. `~/.bashrc`) is definately not. Moreover, it can easily be protected against. Anyone can call `std::ifstream::is_open()` to check if the file succeeded or not. Saying that something is *exceptional* is debatable. Exceptions are to be used in cases where you want to *force* the client to handle the error. This is a useful defensive programming tool when being paranoid about security. – André Caron Dec 15 '10 at 17:29
-
As a matter of interest, here is what MS best practice suggest http://msdn.microsoft.com/en-us/library/seyhszts.aspx - The method you choose depends on how often you expect the event to occur. If the event is truly exceptional and is an error (such as an unexpected end-of-file), using exception handling is better because less code is executed in the normal case. If the event happens routinely, using the programmatic method to check for errors is better. In this case, if an exception occurs, the exception will take longer to handle. – hoakey Dec 20 '10 at 16:16