If a method fails to do what it says it will do (e.g. if SendEmail fails to send an email), it should throw an exception. I blogged about this in-depth (optional read): Do your work, or throw an exception - example. It seems this idea is already a convention, even though I have not found it described elsewhere. "Exceptions are for exceptional cases" is a different guideline requiring an additional guideline "Do not use exceptions for normal flow control", and requiring discussion on what is "exceptional". "Do your work or throw an exception" is as unambiguous as the responsibility of the method (which already should be unambiguous).
All methods, including "Try" methods (e.g. TrySendEmail), should always throw if some unrecoverable error happens--something that adversely affects other features of the app, not just the functionality being attempted, such as RamChipExplodedException. That is, even though "TrySendEmail" technically accomplishes what the name indicates (it tries to send an email), it should still throw an exception if the RAM explodes (if it can even do that... you get my drift).
"Try" methods should be used only in special cases.
Are these always good guidelines (i.e., are there any exceptions (pun!) to the rule)? Can you think of any others not covered by these?
To clarify, I'm not asking for more specific rules of thumb to help follow these guidelines; I'm looking for additional guidelines.
For me, the #1 rule is: avoid exceptions in normal flow. When you debug, make sure all thrown exceptions are signalled. It is the first indication that your code is working the way you designed it.
TryXXX should not throw exceptions unless you violate the design contract. So for instance TrySendMail() may throw if you pass in a null pointer as the text for the email.
You need TryXXX methods if there is no way to get "normal flow" exception free without them. So for parsing data, they're essential, I would not reccomend a TryLogin function.
"Do your work or throw" is a good starting point, but I would not make it a dogma. I am OK with a collection returning -1 if you ask IndexOf an item that isn't there. You can discuss with your colleages where you want to draw the line and put in your coding standards.
I also use exceptions a lot to label control paths that I think are not used. For instance if I am forced to write a GetHashCode function that I assume won't be called, I make it throw.
The fundamental goal of efficient and effective exception handling strategy is for a method to throw exceptions for situations the caller isn't prepared to handle, while letting the caller handle things it is prepared for without the overhead of throwing an exception.
Since functions cannot be clairvoyant with regard to caller expectations, the usual pattern is to have multiple versions of routines where different callers may have different expectations. Someone who decides to call Dictionary.GetValue indicates an expectation that the passed-in key exists in the dictionary. By contrast, someone who calls Dictionary.TryGetValue conveys an expectation that the key may or may not be in a dictionary--either would be reasonably expected. Even in that case, however, the caller probably isn't expecting the CPU to catch fire. If a CpuCaughtFireException occurs in the processing of TryGetValue, it should probably be allowed to propagate up the call stack.
In my opinion, you shouldn't get too hung up about the name "exception" and what exactly is and is not an exceptional situation.
Exceptions are simply another flow control statement, one that allows the flow of control to shortcut up the call stack.
If that's what you need (i.e. you expect immediate calling methods not to be able to handle the condition usefully), use an exception. Otherwise, don't.
I read several posts on exception handling/rethrowing exceptions on here (by looking at the highest voted threads), but I am slightly confused:
-Why would you not want the immediate catch block to handle an exception but rather something above it?
-Also, I read quite frequently that you should only handle exceptions which you can "handle". Does that mean actually doing something about it, such as retrying the operation?
You might want to catch an exception (e.g. file not found) and do some processing - e.g. if you open two files and the second file is missing, you will want to close the first file again before you continue, so that it isn't left open.
You might then want to tell the caller that an error occurred, so you re-throw the same exception or throw a new exception, describing the problem.
In some cases, if you get an exception, your code has no way of knowing if it is an error or not (e.g. if you are asked to load an XML file, but you get a File Not Found exception, is that an error, or should you return a blank XMl result?). In these cases you either want to re-throw the exception, or not handle it all all, and let the calling code decide how to deal with the problem.
Your second point is the answer to the first. Sometimes the lower-level functionality does not know enough about the context of the application to know what the right action should be. For example, if opening a file for reading fails because there is no file of that name, then the application might want to ask for a different file, or abort the whole operation, or whatever. At some level, some part of the application will take the responsibility to do the right thing, unless of course just having the program crash is an acceptable action to take.
Answering to your second question - you need to handle the exception in the immediate block only if can do anything about it: for example close connection to db, close streams, retry or retry with different params, log exception (if there will not be an exception generic handler on the higher levels). Probably only immediate block of code knows such details and can handle them. Calling blocks need to know that the error occurred they might know better what to do with exception.
For example immediate block works with a file. A caller might try to open a file from different locations(In the process of "probing") and ignore several errors as long as at least one succeeds. Another part of code might consider the very first failed attempt as an error. Caller block might chose to notify the user that an error is occurred, probably let her/him know some helpful info on how to fix the problem. Also it is nice to provide the means to notify support of the problem – some kind of dialog allowing user to ask for help, describe problem and send a message. In this message you might attach logs, some info about the environment like OS, versions of frameworks, programs, browser capabilities whatever you need to diagnose the problem (if user permits you to do so).
An exception is "handled" if the method which caught it can satisfy its construct. For example, the contract for a routine OpenRecentDocument which is called when the user selects an item from the "recent files" menu might specify that it must either (1) successfully open a document window, or (2) try unsuccessfully to open a document window, roll back any side-effects resulting from the attempt, and notify the user of the what happened. If OpenRecentDocument catches an exception while trying to open the file, but it is able to roll back any side effects from the attempt and notify the user, the routine will have satisfied its contract and should thus return without rethrowing the exception.
One unfortunate "gotcha" in all this is that there isn't any standard means by which routines which throw an exception can indicate whether their attempted operation has resulted in side-effects which could not be rolled back. There is no inherent way, for example, of distinguishing an InvalidOperationException which occurs unexpectedly while updating a shared data structure (which would imply that other open documents may have been corrupted), from an InvalidOperationException which occurs while updating the data associated with the document being loaded, even if one has anticipated the latter possibility and provided for it. The best one can do is either try to catch any InvalidOperationException which might occur in the latter situation near the spot that it occurs, encapsulate that exception in some other exception type, and throw that, or else have data structures maintain an "object corrupted" flag and ensure that if a data structure is found to be corrupt, all future operations on it will fail as cleanly as possible. Neither approach is at all elegant. The more common approach, which could probably be described as "hope for the best", usually works.
Are there any situations when you would use assertion instead of exceptions-handling inside domain classes...
Use exceptions for parameter validation and other checks which verify that the users of you classes use them as intended.
Use assertions for internal consistency checks, i.e. to indicate you screwed up, not the user of your class.
Thus, if users of your class see an assertion failure, they know it is (probably) an internal error in your code, not in their use of your code. On the other hand, if the get parameter validation exception, they know it's their fault.
Never. Assertions are not a valid form of error-handling. Use them to assist in identifying program errors during testing.
An assertion reflects a state that should not ever occur and was not expected, where the application cannot continue executing for one reason or another, whereas an exception indicates a state that is not considered "normal", but that was not unexpected, and from which it might be possible to recover.
As an example, if I allocate space on the heap, and this allocation fails, then I can't continue working, so I assert that the address returned is valid; where it is invalid, the assertion fails, and the program fails with it.
On the other hand, if I open a file for reading, and it doesn't exist, then it might be possible to recover from the situation, in which case an exception is thrown (and caught, and handled as far as possible).
In general, assertions are most useful during the debugging phase, whereas exceptions are considered part of regular program flow and error handling. The general consensus is that assertions should be disabled in production code (to shield users from apparent crashes), whereas I have read a school of thought that argues this is counter-productive, and that the user should see the assertion failure, so that they can properly report the problem.
Personally, I sometimes combine the two techniques; usually, if I'm catching an exception that I do not believe could be thrown. Taking the example above, if I check the file's existence before attempting to open it, then I do not expect an exception to be thrown, and if one is, then I tend to deal with this by raising an assertion in the relevant catch block. I find this a particularly useful technique in Java, where such exceptions are fully checked.
A lot of developers say only throw exceptions in truly exceptional circumstances. One of these would be if an external hard drive I want to write to is not switched on (therefore not a connected/registered drive). However, there are some situations which are difficult to work out whether they are truly exceptional or not.
For example, entering a string for a folder path but it is not found. In this case, if there is any input which cannot be found (like a name in a collection which is not found), is it best to just return an error message and some action?
E.G.
public void Find(string name)
{
if(Names.contains(name)
{
string s = Names.get(name);
}
if(!Names.contains(string name)
{
throw new ???Exception;
}
}
Or do something like display a popup and handle the situation gracefully?
Is it wise to throw an exception in an else or if statement? Looking at a list of code smells regarding exception handling would do me a lot of favours.
Generally, it works like this:
If you can handle the situation without any interruptions, do so. (File doesn't exist, but its input isn't essential to continuing operation [preferences, optional configuration, etc])
If you need user intervention, ask them. (File doesn't exist, but you need it to continue operating)
If it's a problem the user can't fix (out-of-memory, failed hardware, etc), then throw an exception.
Each place has their own standard for the details, but I find the above to work generally.
if your code can recover from the exception, do so
if it would be acceptable to require clients to check a return value for minor expected exceptions, do so - this is a judgement call, see below
in all other cases, throw an exception (or don't catch a called method's exception)
for the second case, minor and expected are highly context-sensitive
IMHO don't use exceptions for control-flow, but in all other cases you are probably safer throwing them
note that some 'optimization' advice tells you to check for conditions instead of relying on exceptions, e.g. file-not-found, but in reality you should still expect the exception because a file may be deleted or moved in between the statement that checks for existence and the statement that tries to open the file!
summary: in general, throwing exceptions is the safest course. Of course, directly warning or asking the user should only be done in the user-interface code!
Exceptions should be used if there is something that can be done about it, but the code that detects it can't known what to do.
I understand that "Exceptions are for exceptional cases" [a], but besides just being repeated over and over again, I've never found an actual reason for this fact.
Being that they halt execution, it makes sense that you wouldn't want them for plain conditional logic, but why not input validation?
Say you were to loop through a group of inputs and catch each exception to group them together for user notification... I continually see that this is somehow "wrong" because users enter incorrect input all the time, but that point seems to be based on semantics.
The input is Not what was expected and hence is exceptional. Throwing an exception allows me to define exactly what was wrong like StringValueTooLong or or IntegerValueTooLow or InvalidDateValue or whatever. Why is this considered wrong?
Alternatives to throwing an exception would be to either return (and eventually collect) an error code or far worse an error string. Then I would either show those error strings directly, or parse the error codes and then show corresponding error messages to the user. Wouldn't a exception be considered a malleable error code? Why create a separate table of error codes and messages, when these could be generalized with the exception functionality already built into my language?
Also, I found this article by Martin Fowler as to how to handle such things - the Notification pattern. I'm not sure how I see this as being anything other than Exceptions that don't halt execution.
a: Everywhere I've read anything about Exceptions.
--- Edit ---
Many great points have been made. I've commented on most and +'d the good points, but I'm not yet completely convinced.
I don't mean to advocate Exceptions as the proper means to resolve Input Validation, but I would like to find good reasons why the practice is considered so evil when it seems most alternate solutions are just Exceptions in disguise.
Reading these answers, I find it very unhelpful to say, "Exceptions should only be used for exceptional conditions". This begs the whole question of what is an "exceptional condition". This is a subjective term, the best definition of which is "any condition that your normal logic flow doesn't deal with". In other words, an exceptional condition is any condition you deal with using exceptions.
I'm fine with that as a definition, I don't know that we'll get any closer than that anyway. But you should know that that's the definition you are using.
If you are going to argue against exceptions in a certain case, you have to explain how to divide the universe of conditions into "exceptional" and "non-exceptional".
In some ways, it's similar to answering the question, "where are the boundaries between procedures?" The answer is, "Wherever you put the begin and end", and then we can talk about rules of thumb and different styles for determining where to put them. There are no hard and fast rules.
A user entering 'bad' input is not an exception: it's to be expected.
Exceptions should not be used for normal control flow.
In the past many authors have said that Exceptions are inherently expensive. Jon Skeet has blogged contrary to this (and mentioned a few time in answers here on SO), saying that they are not as expensive as reported (although I wouldn’t advocate using them in a tight loop!)
The biggest reason to use them is ‘statement of intent’ i.e. if you see an exception handling block you immediately see the exceptional cases which are dealt with outside of normal flow.
There is one important other reason than the ones mentioned already:
If you use exceptions only for exceptional cases you can run in your debugger with the debugger setting "stop when exception is thrown". This is extremely convenient because you drop into the debugger on the exact line that is causing the problem. Using this feature saves you a fair amount of time every day.
In C# this is possible (and I recommend it wholeheartedly), especially after they added the TryParse methods to all the number classes. In general, none of the standard libraries require or use "bad" exception handling. When I approach a C# codebase that has not been written to this standard, I always end up converting it to exception-free-for-regular cases, because the stop-om-throw is so valuable.
In the firebug javascript debugger you can also do this, provided that your libraries don't use exceptions badly.
When I program Java, this is not really possible because so many things uses exceptions for non-exceptional cases, including a lot of the standard java libraries. So this time-saving feature is not really available for use in java. I believe this is due to checked exceptions, but I won't start ranting about how they are evil.
Errors and Exceptions – What, When and Where?
Exceptions are intended to report errors, thereby making code more robust. To understand when to use exceptions, one must first understand what errors are and what is not an error.
A function is a unit of work, and failures should be viewed as errors or otherwise based on their impact on functions. Within a function f, a failure is an error if and only if it prevents f from meeting any of its callee’s preconditions, achieving any of f’s own postconditions, or reestablishing any invariant that f shares responsibility for maintaining.
There are three kinds of errors:
a condition that prevents the function from meeting a precondition (e.g., a parameter restriction) of another function that must be called;
a condition that prevents the function from establishing one of its own postconditions (e.g., producing a valid return value is a postcondition); and
a condition that prevents the function from re-establishing an invariant that it is responsible for maintaining. This is a special kind of postcondition that applies particularly to member functions. An essential postcondition of every non-private member function is that it must re-establish its class’s invariants.
Any other condition is not an error and should not be reported as an error.
Why are Exceptions said to be so bad for Input Validation?
I guess it is because of a somewhat ambiguous understanding of “input” as either meaning input of a function or value of a field, where the latter should’t throw an exception unless it is part of a failing function.
Maintainability - Exceptions create
odd code paths, not unlike GOTOs.
Ease of Use (for other classes) -
Other classes can trust that
exceptions raised from your user
input class are actual errors
Performance - In most languages, an
exception incurs a performance and
memory usage penalty.
Semantics - The meaning of words
does matter. Bad input is not
"exceptional".
I think the difference depends on the contract of the particular class, i.e.
For code that is meant to deal with user input, and program defensively for it (i.e. sanitise it) it would be wrong to throw an exception for invalid input - it is expected.
For code that is meant to deal with already sanitised and validated input, which may have originated with the user, throwing an exception would be valid if you found some input that is meant to be forbidden. The calling code is violating the contract in that case, and it indicates a bug in the sanitising and/or calling code.
When using exceptions, the error handling code is separated from the code causing the error. This is the intent of exception handling - being an exceptional condition, the error can not be handled locally, so an exception is thrown to some higher (and unknown) scope. If not handled, the application will exit before any more hard is done.
If you ever, ever, ever throw exception when you are doing simple logic operations, like verifying user input, you are doing something very, very very, wrong.
The input is Not what was expected and
hence is exceptional.
This statement does not sit well with me at all. Either the UI constrains user input (eg, the use of a slider that bounds min/max values) and you can now assert certain conditions - no error handling required. Or, the user can enter rubbish and you expect this to happen and must handle it. One or the other - there is nothing exception going here whatsoever.
Throwing an exception allows me to
define exactly what was wrong like
StringValueTooLong or or
IntegerValueTooLow or InvalidDateValue
or whatever. Why is this considered
wrong?
I consider this beyond - closer to evil. You can define an abstract ErrorProvider interface, or return a complex object representing the error rather than a simple code. There are many, many options on how you retrieve error reports. Using exceptions because the are convenient is so, so wrong. I feel dirty just writing this paragraph.
Think of throwing an exception as hope. A last chance. A prayer. Validating user input should not lead to any of these conditions.
Is it possible that some of the disagreement is due to a lack of consensus about what 'user input' means? And indeed, at what layer you're coding.
If you're coding a GUI user interface, or a Web form handler, you might well expect invalid input, since it's come direct from the typing fingers of a human being.
If you're coding the model part of an MVC app, you may have engineered things so that the controller has sanitised inputs for you. Invalid input getting as far as the Model would indeed be an exception, and may be treated as such.
If you're coding a server at the protocol level, you might reasonably expect the client to be checking user input. Again, invalid input here would indeed be an exception. This is quite different from trusting the client 100% (that would be very stupid indeed) - but unlike direct user input, you predict that most of the time inputs would be OK. The lines blur here somewhat. The more likely it is that something happens, the less you want to use exceptions to handle it.
This is a linguistic pov( point of view) on the matter.
Why are Exceptions said to be so bad for Input Validation?
conclusion :
Exceptions are not defined clearly enough, so there are different opinions.
Wrong input is seen as a normal thing, not as an exception.
thoughts ?
It probably comes down to the expectations one takes about the code that is created.
the client can not be trusted
validation has to happen at the server's side.
stronger : every validation happens at server's side.
because validation happens at the server's side it is expected to be done there and what is expected is not an exception, since it is expected.
However,
the client's input can not to be trusted
the client's input-validation can be trusted
if validation is trusted it can be expected to produce valid input
now every input is expected to be valid
invalid input is now unexpected, an exception
.
exceptions can be a nice way to exit the code.
A thing mentioned to consider is if your code is left in a proper state.
I would not know what would leave my code in an improper state.
Connections get closed automatically, leftover variables are garbage-collected, what's the problem?
Another vote against exception handling for things that aren't exceptions!
In .NET the JIT compiler won't perform optimizations in certain cases even when exceptions aren't thrown. The following articles explain it well.
http://msmvps.com/blogs/peterritchie/archive/2007/06/22/performance-implications-of-try-catch-finally.aspx
http://msmvps.com/blogs/peterritchie/archive/2007/07/12/performance-implications-of-try-catch-finally-part-two.aspx
When an exception gets thrown it generates a whole bunch of information for the stack trace which may not be needed if you were actually "expecting" the exception as is often the case when converting strings to int's etc...
In general, libraries throw exceptions and clients catch them and do something intelligent with them. For user input I just write validation functions instead of throwing exceptions. Exceptions seem excessive for something like that.
There are performance issues with exceptions, but in GUI code you won't generally have to worry about them. So what if a validation takes an extra 100 ms to run? The user isn't going to notice that.
In some ways it's a tough call - On the one hand, you might not want to have your entire application come crashing down because the user entered an extra digit in a zip code text box and you forgot to handle the exception. On the other, a 'fail early, fail hard' approach ensures that bugs get discovered and fixed quickly and keeps your precious database sane. In general I think most frameworks recommend that you don't use exception handling for UI error checking and some, like .NET Windows Forms, provide nice ways to do this (ErrorProviders and Validation events) without exceptions.
Exceptions should not be used for input validation, because not only should exceptions be used in exceptional circumstances (which as it has been pointed out incorrect user entry is not) but they create exceptional code (not in the brilliant sense).
The problem with exceptions in most languages is they change the rules of program flow, this is fine in a truly exceptional circumstance where it is not necessarily possible to figure our what the valid flow should be and therefore just throw an exception and get out however where you know what the flow should be you should create that flow (in the case listed it would be to raise a message to the user telling them they need to reenter some information).
Exceptions were truly overused in an application I work on daily and even for the case where a user entered an incorrect password when logging in, which by your logic would be an exception result because it is not what the application wants. However when a process has one of two outcomes either correct or incorrect, I dont think we can say that, incorrect, no matter how wrong, is exceptional.
One of the major problems I have found with working with this code is trying to follow the logic of the code without getting deeply involved with the debugger. Although debuggers are great, it should be possible to add logic to what happens when a user enters an incorrect password without having to fire one up.
Keep exceptions for truly exceptional execution not just wrong. In the case I was highlighting getting your password wrong is not exceptional, but not being able to contact the domain server may be!
When I see exceptions being thrown for validation errors I often see that the method throwing the exception is performing lots of validations all at once. e.g.
public bool isValidDate(string date)
{
bool retVal = true;
//check for 4 digit year
throw new FourDigitYearRequiredException();
retVal = false;
//check for leap years
throw new NoFeb29InANonLeapYearException();
retVal = false;
return retVal;
}
This code tends to be pretty fragile and hard to maintain as the rules pile up over the months and years. I usually prefer to break up my validations into smaller methods that return bools. It makes it easier to tweak the rules.
public bool isValidDate(string date)
{
bool retVal = false;
retVal = doesDateContainAFourDigitYear(date);
retVal = isDateInALeapYear(date);
return retVal;
}
public bool isDateInALeapYear(string date){}
public bool doesDateContainAFourDigitYear(string date){}
As has been mentioned already, returning an error struct/object containing information about the error is a great idea. The most obvious advantage being that you can collect them up and display all of the error messages to the user at once instead of making them play Whack-A-Mole with the validation.
i used a combination of both a solution:
for each validation function, i pass a record that i fill with the validation status (an error code).
at the end of the function, if a validation error exists, i throw an exception, this way i do not throw an exception for each field, but only once. i also took advantage that throwing an exception will stop execution because i do not want the execution to continue when data is invalid.
for example
procedure Validate(var R:TValidationRecord);
begin
if Field1 is not valid then
begin
R.Field1ErrorCode=SomeErrorCode;
ErrorFlag := True;
end;
if Field2 is not valid then
begin
R.Field2ErrorCode=SomeErrorCode;
ErrorFlag := True;
end;
if Field3 is not valid then
begin
R.Field3ErrorCode=SomeErrorCode;
ErrorFlag := True;
end;
if ErrorFlag then
ThrowException
end;
if relying on boolean only, the developer using my function should take this into account writing:
if not Validate() then
DoNotContinue();
but he may forgot and only call Validate() (i know that he should not, but maybe he might).
so, in the code above i gained the two advantages:
1-only one exception in the validation function.
2-exception, even uncaught, will stop the execution, and appear at test time.
8 years later, and I'm running into the same dilemma trying to apply the CQS pattern. I'm on the side that input validation can throw an exception, but with an added constraint. If any input fails, you need to throw ONE type of exception: ValidationException, BrokenRuleException, etc. Don't throw a bunch of different types as it'll be impossible to handle them all. This way, you get a list of all the broken rules in one place. You create a single class that is responsible for doing validation (SRP) and throw an exception if at least 1 rule is broken. That way, you handle one situation with one catch and you know you are good. You can handle that scenario no matter what code is called. This leaves all the code downstream much cleaner as you know it is in a valid state or it wouldn't have gotten there.
To me, getting invalid data from a user is not something you would normally expect. (If every user sends invalid data to you the first time, I'd take a second look at your UI.) Any data that prevents you from processing the true intent whether it is user or sourced elsewhere needs to abort processing. How is it any different than throwing an ArgumentNullException from a single piece of data if it was user input vs. it being a field on a class that says This is required.
Sure, you could do validation first and write that same boilerplate code on every single "command", but I think that is a maintenance nightmare than catching invalid user input all in one place at the top that gets handled the same way regardless. (Less code!) The performance hit will only come if the user gives invalid data, which should not happen that often (or you have bad UI). Any and all rules on the client side have to be re-written on the server, anyway, so you could just write them once, do an AJAX call, and the < 500 ms delay will save you a ton of coding time (only 1 place to put all your validation logic).
Also, while you can do some neat validation with ASP.NET out of the box, if you want to re-use your validation logic in other UIs, you can't since it is baked into ASP.NET. You'd be better off creating something below and handling it above regardless of the UI being used. (My 2 cents, at least.)
I agree with Mitch that that "Exceptions should not be used for normal control flow". I just want to add that from what I remember from my computer science classes, catching exceptions is expensive. I've never really tried to do benchmarks, but it would be interesting to compare performance between say, an if/else vs try/catch.
One problem with using exceptions is a tendency to detect only one problem at a time. The user fixes that and resubmits, only to find another problem! An interface that returns a list of issues that need resolving is much friendlier (though it could be wrapped in an exception).