50

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.

Community
  • 1
  • 1
enobrev
  • 22,314
  • 7
  • 42
  • 53
  • 1
    I agree. I want to separate the input validation and the showing of the error message. Same error message showing can handle both invalid input and internal error cases just find. – iny Jan 04 '09 at 10:27

17 Answers17

30

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.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • 1
    Thank you sir. You have helped define my frustration with these otherwise great answers. I keep getting the same one!! – enobrev Jan 04 '09 at 17:47
  • 1
    +1: Agreed! In my mind an "Exception" (noun) is not short for Exceptional (adj.), it's just what it says it is, an Exception. As in "an instance or case not conforming to the general rule". I supposed you COULD have an exceptional exception though. ;) – techie007 Aug 26 '12 at 20:59
  • 4
    It's worth mentioning that Martin Fowler presents Exception based flow control as a desirable refactoring pattern in **Refactoring** – ocodo Jan 17 '13 at 05:27
  • One example I think is an 'exceptional condition' is: whenever a business rule on domain entities are violated. The exception here is to alert the programmer to do checks before c(r)ud-ing any entity. Rule of thumb could be "A domain entity should never be in a invalid state" – Highmastdon Dec 16 '14 at 13:40
22

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.

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
  • Good Article, Mitch ( http://www.yoda.arachsys.com/csharp/exceptions.html ), thanks for that - though this isn't very convincing otherwise. – enobrev Jan 04 '09 at 07:10
  • 3
    Sorry, I'll take that further. "to be expected" is a hard argument to make. All exceptions are to be expected. We couldn't write them otherwise. I agree (and stated) about control flow). And wouldn't using exceptions for input validation include that state of intent? – enobrev Jan 04 '09 at 07:19
  • @enobrev: you seem to be misunderstanding what an exception is. It is something that within normal operating conditions should not occur. – Mitch Wheat May 11 '09 at 08:13
  • 1
    @mitch: unfortunately, that just raises the question, "What are normal operating conditions?" Since pretty much everyone will have a different definition of that it makes it hard to define an exception. – Sailing Judo Jun 19 '09 at 14:31
  • 3
    @Sailing Judo: It depends on context. AN application being unable to open a required file that is owned by that application and expected to be open-able is an exception. – Mitch Wheat Jun 19 '09 at 17:15
8

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.

krosenvold
  • 75,535
  • 32
  • 152
  • 208
  • Good point, krosenvold. I guess I was hoping for that rant about evil exceptions, actually. I'm not entirely sold on how absolutely evil they are. – enobrev Jan 04 '09 at 07:23
  • 1
    Well they are the cause of me not being able to use "stop on throw" in java. Evil by itself, since it's a GOOD THING. – krosenvold Jan 04 '09 at 07:38
  • Very interesting point on the Debugger stop at every exception thrown (Unless I'm wrong, it's called first chance exception in VS 2003)... I wonder if there is a way in the debugger to ask it to ignore exceptions of some types, and stop at others... +1 ... – paercebal Jan 04 '09 at 12:04
  • @paercebal Eclipse allows you to specify which classes of exception will be caught. It defaults to *Exception* (wild card to match all exceptions). In the debug perspective, click Run -> Add Java Exception Breakpoint... – David Mann Feb 07 '13 at 15:46
7

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.

Frederik Krautwald
  • 1,782
  • 23
  • 32
5
  1. Maintainability - Exceptions create odd code paths, not unlike GOTOs.
  2. Ease of Use (for other classes) - Other classes can trust that exceptions raised from your user input class are actual errors
  3. Performance - In most languages, an exception incurs a performance and memory usage penalty.
  4. Semantics - The meaning of words does matter. Bad input is not "exceptional".
JosephStyons
  • 57,317
  • 63
  • 160
  • 234
  • What I really mean is "non-obvious", as in someone new to the code won't necessarily anticipate where the code will go. – JosephStyons Jan 04 '09 at 06:39
  • It seems hard to define how obvious input validation is. Receiving "Banana" for an age field seems pretty non-obvious. A loop could be considered a goto, but we know where it's going. I get what you mean about the code paths, but they're deliberate. – enobrev Jan 04 '09 at 07:17
  • I can't take credit. Others have said similar things. I definitely thing exceptions are a great tool, but for a slightly harsher view of things, check this out: http://www.joelonsoftware.com/items/2003/10/13.html – JosephStyons Jan 05 '09 at 15:56
  • Performance of human brain is definitely much lower than the slowest exception implementation; the performance argument is straw man when talking about exception in input. Classes that uses error codes are not easier to use; they are only easier for ignoring errors (including input errors). "odd code path", wtf is that supposed to mean? Everyone that have ever used exceptions knows that exception has a clearly defined code path: UP. "Bad input is not exceptional" is subjective, one could argue that the user should ideally never put in bad input, so bad input is therefore exceptional. – Lie Ryan May 25 '11 at 15:17
5

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.

frankodwyer
  • 13,948
  • 9
  • 50
  • 70
  • I see what you're saying and it makes sense while falling in line with what I've read about exceptions in general, but how is using another method for catching and resolving the invalid input any better or more "right" than using an exception? – enobrev Jan 04 '09 at 10:27
  • 1
    i think because it is part of the normal program flow to do so. normally exceptions allow you to keep your code flow clean by coding only for the normal business cases and ignoring (literally) exceptional cases that shouldn't normally happen (e.g. runtime issues like out of disk space, out of mem). – frankodwyer Jan 04 '09 at 10:33
  • 1
    But with incorrect user input, you're going to eventually halt all execution and ask the user to resolve the problem, which sounds a lot like an exception. – enobrev Jan 04 '09 at 17:49
  • 1
    @enobrev: In "friendly" client-side code, invalid user input won't just stop everything and say "something is wrong", but will instead describe the particular problems and help the user fix it (e.g. by highlighting invalid fields). Code to handle a particular problem should be located near code where the problem could occur (suggesting error-checking would be more appropriate than exception handling). Exception handling is more appropriate in cases where many problems should be handled the same way (e.g. receiving a submission from apparently-faulty client-side code). – supercat Sep 13 '13 at 15:40
3

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.

Daniel Paull
  • 6,797
  • 3
  • 32
  • 41
  • Fine points Daniel, thank you. "the error can not be handled locally" - Isn't that a part of input validation? There was a problem with the input and now you have to ask the user to resolve the issue. You're catching the exception and asking the user to resolve it before you can continue. – enobrev Jan 04 '09 at 09:11
  • "Either the UI constrains user input... Or, the user can enter rubbish and you expect this to happen" This isn't always possible - say in the instance of the web, where inputs must eventually be handled by the business logic. – enobrev Jan 04 '09 at 09:13
  • Isn't an "ErrorProvider" that eventually bubbles up to the user interface to be resolved the same as an Exception caught by your View or Display logic? – enobrev Jan 04 '09 at 09:14
  • 1
    @enobrev: to your fist two points - why *must* exceptions be used in this scenario? Exceptions are a big-gun and should only be used where there is no alternative. – Daniel Paull Jan 04 '09 at 09:22
  • @enobrev: To the 3rd, similar other than the the way exceptions alter control flow - they are abrupt and halt execution. Callers must be very careful to leave the application in a sane state when exceptions are being thrown. It's nasty, nasty stuff and not given enough thought by most programmers. – Daniel Paull Jan 04 '09 at 09:24
  • Thanks again for the good responses, Daniel! I guess part of my confusion is the actual halting of execution is meaningfully and expectedly caught and dealt with accordingly. I agree that leaving the application in a sane state is top priority. It seems this can be easily managed with exceptions. – enobrev Jan 04 '09 at 09:27
  • It can only be "easily managed with exceptions" when you expect an exception to be thrown. This is not an Exception, it's an Expectation and a misuse of exception handling - tread carefully! – Daniel Paull Jan 04 '09 at 11:30
  • It seems we always expect a user-defined (well, developer-defined) exception to be thrown. That's why we wrote the exception in the first place. I do tread lightly with exceptions as, when uncaught, their not very user friendly, but that doesn't seem a good reason to avoid them. – enobrev Jan 04 '09 at 17:52
  • Correct exception handing, especially in a language that does not support the RAII pattern is very difficult. The separation of error handling from where the error occurred makes it hard to understand the code. There are many reasons why the use of exceptions should be avoided where possible. – Daniel Paull Jan 04 '09 at 23:41
3

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.

slim
  • 40,215
  • 13
  • 94
  • 127
  • Good points, but what if we are talking about the thinnest of clients - say user input on a web page with javascript validation. Why would it be wrong to use exceptions while checking the user-entered values? How is any other method (events, error codes, custom error classes, etc) more correct? – enobrev Jan 04 '09 at 11:10
  • I did consider mentioning Javascript form validation, but felt it muddied the point. I would say that on the spectrum of 'always' to 'never' use exceptions, Javascript validation edges you away from 'never' – slim Jan 04 '09 at 11:32
  • ... but it would mean that a script kiddie could easily cause your Web app to throw exceptions all over the place. Unless users are authenticated and trusted to behave. So many factors! – slim Jan 04 '09 at 11:34
  • Well, if you're explicitly catching those exceptions in any code that calls your validation routine, this shouldn't even be an afterthought. – enobrev Jan 04 '09 at 17:48
  • The point being that people claim that throwing exceptions is expensive. It would be a potential denial of service attack. – slim Jan 04 '09 at 18:19
3

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?

imme
  • 598
  • 1
  • 9
  • 22
2

Another vote against exception handling for things that aren't exceptions!

  1. 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

  2. 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...

Alex
  • 34,776
  • 10
  • 53
  • 68
  • Good points related to performance, which seems to differ from language to language. In the case of managing input, it seems performance may not always be as high a priority as something that will likely happen once upon input submission. – enobrev Jan 04 '09 at 09:18
2

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.)

Daniel Lorenz
  • 4,178
  • 1
  • 32
  • 39
  • Kinda funny. 5 years later and I reversed my opinion on this 100%. You'd expect the client to send you bad data - though, you can prevent a lot of it. If you have something in place that can return a 400 with the list of broken rules before hitting your main code logic, then there isn't a need to throw an exception. Exceptions are actually pretty expensive, so try to avoid them as much as possible. – Daniel Lorenz May 04 '23 at 15:45
1

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.

Bahaa
  • 123
  • 2
  • 9
1

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.

Dana Robinson
  • 4,304
  • 8
  • 33
  • 41
  • I'm a Windows Forms programmer so I use Error Providers and the Validation events to handle everything. In other languages I'd look for similar functionality or have something like validation functions that return bool values and use out parameters for descriptive messages. – Dana Robinson Jan 04 '09 at 07:07
  • Thanks Dana, Now I could be wrong (I had to look both up), but it seems to me that a Validation Event is a non-halting exception and an ErrorProvider is an extension to that Event that leads all the way to displaying the error near the form field. I'm not sure I see the difference. – enobrev Jan 04 '09 at 07:15
  • The validation events are just events, like button clicks and the like. They aren't exceptions at all. An event does not inherit from System.Exception. – Dana Robinson Jan 04 '09 at 07:23
  • I understand that, but I'm not sure I see the functional difference. After all, an exception in any language is merely an object that is returned from a halted method. Besides the halting, how is that so different from an event object? – enobrev Jan 04 '09 at 07:27
  • An event is just a way of calling a method. An exception causes the runtime to jump out of the normal control flow so it can get ready to kill it, hence the performance hit. – Dana Robinson Jan 04 '09 at 07:43
  • In the .NET world, Essential .NET Volume 1 by Don Box is probably the best at describing what's going on at the runtime level. – Dana Robinson Jan 04 '09 at 07:47
1

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!

Toby Allen
  • 10,997
  • 11
  • 73
  • 124
  • I understand and feel your pain about a poorly designed applications. But I'd be willing to bet that the headaches stem from far more than throwing exceptions for validation, since input validation tends to be such a small portion of a well designed application. – enobrev Jan 04 '09 at 17:57
  • It's often helpful for routines to have both "Do" and "Try" versions, with the "Do" version throwing an exception if it fails. This means that code which has a fallback position if an operation fails can handle such failure without an exception getting thrown, and code which has no fallback position can fail fast without explicit error handling. – supercat Jan 06 '11 at 22:12
1

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.

ScottKoon
  • 3,483
  • 6
  • 27
  • 29
  • I understand and agree with your point about putting all the validation in one place, but isn't an exception the same as "returning an error struct/object containing information about the error"? – enobrev Jan 27 '09 at 21:16
  • Fundamentally yes, Except that the system treats exceptions differently. Exceptions stop/interrupt the flow of your code, you have to stop and deal with an exception. – ScottKoon Jan 27 '09 at 22:14
0

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.

barneytron
  • 7,943
  • 3
  • 23
  • 25
  • Thanks for the response Barneytron, though Mitch made a good point about this article that states otherwise: http://www.yoda.arachsys.com/csharp/exceptions.html – enobrev Jan 04 '09 at 07:21
  • Wow, thanks for the link enobrev. Looks like Mitch added more info the the original response. That's really good stuff! – barneytron Jan 04 '09 at 19:58
0

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).

asplake
  • 177
  • 4
  • Sure, but you could potentially catch and collect Exceptions. – enobrev Jan 04 '09 at 17:44
  • 1
    much better is an input that detects errors as you type (on the web this will require javascript). By the time the user submits, the input is always already clean and then the server had to do validations only for security purpose. Exceptions would do fine in this scenario. – Lie Ryan May 25 '11 at 15:26