Why are Exceptions considered so bad for incoming validation?

I understand that “Exceptions for exceptional cases” [a], but besides the fact that they are repeated over and over , I never found a real reason for this fact.

Since they stop execution, it makes sense that you do not want them for simple conditional logic, but why not introduce a check?

Say that you had to go through a group of inputs and catch each exception in order to group them together to notify the user ... I constantly see that this is somehow "wrong" because users enter the wrong input all the time, but this point seems based on semantics .

Entrance is not expected and therefore is exceptional. Throwing an exception allows me to pinpoint what was wrong, like StringValueTooLong or IntegerValueTooLow or InvalidDateValue or something else. Why is this considered wrong?

An alternative to throwing an exception is either returning (and, ultimately, collecting) the error code, or even worse is the error string. Then I would either show these error lines directly, or analyze the error codes, and then display the corresponding error messages to the user. Wouldn't an exception be considered a malleable error code? Why create a separate table of error codes and messages when they can be generalized using the exception function already built into my language?

Also, I found this Martin Fowler article on how to handle such things - a notification template. I am not sure how I see this as anything other than Exceptions, which do not stop execution.

a: Everywhere I read something about Exceptions.

--- Edit ---

Many wonderful comments were made. I have commented on most and good reviews, but I am not yet fully convinced.

I don’t want to defend 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 that most of the alternative solutions are just masked Exceptions.

+43
validation exception error-handling
Jan 04 '09 at 6:25
source share
17 answers

Reading these answers, I find it futile to say: “Exceptions should only be used for exceptional conditions.” This asks the whole question of what an “exceptional condition” is. This is a subjective term, the best definition of which is "any condition with which a normal logical flow is not related." In other words, an exceptional condition is any condition that you deal with using exceptions.

I am fine with this, as a definition, I don’t know that we will come nearer to this anyway. But you should know that this is the definition you are using.

If you are going to argue about exceptions in a particular case, you must explain how to divide the universe of conditions into “exceptional” and “non-exclusive”.

In a way, this is similar to the answer to the question: "Where are the boundaries between the procedures?" Answer: “Wherever you start and end,” and then we can talk about rules of thumb and different styles to determine where to place them. There are no hard and fast rules.

+28
Jan 04 '09 at 13:12
source share

A user entering a "bad" entry is no exception: you can expect it.

Exceptions should not be used for normal control flow.

In the past, many authors have said that exceptions are initially expensive. John Skeet wrote a blog against this (and mentioned several times in the answers here on SO), saying that they are not as expensive as reported (although I would not use them in a difficult cycle!)

The biggest reason for using them is an “expression of intent, that is, if you see an exception handling block, you will immediately see exceptional cases that are considered outside the normal flow.

+19
Jan 04 '09 at 6:27
source share

There is one important reason besides those already mentioned:

If you use exceptions only for exceptional cases, you can run in your debugger with the debugger setting "stop when throw is throw". This is very convenient because you get into the debugger on the exact line that is causing the problem. Using this feature saves you a lot of time every day.

In C #, this is possible (and I recommend it completely), especially after they have added TryParse methods to all number classes. In general, none of the standard libraries require or use "bad" exception handling. When I approach a C # codebase that was not written on this standard, I always end up converting it to exceptions due to common cases, because stop-om-throw is so valuable.

You can also do this in the javascript firebug debugger, provided that your libraries make poor use of exceptions.

When I program Java, this is actually impossible, because many things use exceptions for non-exceptional cases, including many standard java libraries. Thus, this time saving feature is not available for use in java. I believe this is due to checked exceptions, but I will not begin to rant about how evil they are.

+8
Jan 04 '09 at 7:08
source share

Errors and exceptions - what, when and where?

Exceptions are for reporting errors, which makes the code more reliable. To understand when to use exceptions, you first need to understand what errors are and what is not an error.

A function is a unit of work, and errors should be treated as errors or otherwise based on their effect on functions. Inside the function f, an error is an error if and only if it prevents f from fulfilling any preconditions of the call by reaching any of f or restoring any invariant that f shares the responsibility of maintaining.

There are three types of errors:

  • a condition that does not allow the function to fulfill a precondition (for example, a parameter constraint) of another function that must be called;
  • a condition that prevents the function from setting one of its own postconditions (for example, creating a valid return value is a postcondition); and
  • a condition that does not allow the function to reinstall the invariant that is responsible for maintaining. This is a special postcondition that applies especially to member functions. An essential postcondition for each infrequent member function is that it must restore the invariants of its classes.

Any other condition is not an error and should not be reported as an error.

Why are Exceptions considered so bad for incoming validation?

I suppose this is due to a somewhat ambiguous understanding of “input” as a function input value or a field value where the latter should throw an exception if it is not part of the failure function.

+6
Jul 10 '14 at 13:14
source share

I think the difference depends on the contract of a particular class, i.e.

For code intended to work with user inputs and to protect the program (i.e., to clear it), it would be wrong to throw an exception for invalid input - expected.

For a code that is designed to handle an already sanitized and verified input that the user may experience, an exception throw will be valid if you find some input that should be prohibited. In this case, the calling code violates the contract and indicates an error in the code to clear and / or call.

+5
Jan 04 '09 at 10:14
source share
  • Maintaining Health - Exceptions create odd code codes, unlike GOTO.
  • Ease of use (for other classes) - Other classes can trust that the exceptions received from your user input class are actual errors.
  • Performance . In most languages, memory usage is an exception.
  • Semantics . The meaning of words matters. Bad input is not "Exceptional."
+4
Jan 04 '09 at 6:34
source share

Is it possible that some disagreement is due to a lack of consensus on what user input means? And really, at what level are you coding.

If you are coding a GUI or web form handler, you can expect invalid input because it comes directly from a person’s fingerprint.

If you code the model part of an MVC application, you may have designed things so that the controller will sanitize the input for you. Invalid data entry because the Model is indeed an exception and may be considered as such.

If you encode the server at the protocol level, you can reasonably expect the client to validate user input. Again, incorrect input here will really be an exception. This is not at all like trusting a client 100% (that would be very stupid) - but, unlike direct user input, you predict that most of the input will be fine. The lines are blurry here a little. The more likely that something happens, the less you want to use exceptions to handle it.

+3
Jan 04 '09 at 11:05
source share

This is a linguistic pov (point of view) on this subject.

Why are Exceptions considered so bad for incoming validation?

conclusion:

  • Exceptions are not clearly defined, so there are different opinions.
  • Invalid input is considered a normal thing, not an exception.

thoughts?

This is likely due to expectations about creating code.

  • The customer cannot be trusted
    • verification must be done on the server side. stronger: each check is done on the server side.
    • since the check is performed on the server side, it is expected to be performed there, and the expected is no exception, as it is expected.

However

  • you cannot <trust << →
  • you can trust the client with confirmation of input
    • If the power of attorney is verified, it can be expected that it will produce valid input
    • each entry is now expected to be valid.
    • incorrect input is now unexpected, exception

.

exceptions can be a good way to exit the code.

Keep in mind that your code remains in the correct state. I do not know what will leave my code in poor condition. Connections are automatically closed, the remaining variables are garbage collected, what's the problem?

+3
Dec 31 '10 at 16:18
source share

When using exceptions , the error handling code is separate from the code that causes the error . This intention to handle exceptions is an exceptional condition, the error cannot be processed locally, so the exception is passed to some higher (and unknown) area. If not processed, the application will exit before the more complex one is executed.

If you ever ever throw an exception when you perform simple logical operations, for example, checking user input, you are doing something very, very very, wrong.

Input is not what was expected, and therefore is exceptional.

This statement does not quite fit me. Or the user interface restricts user input (for example, using a slider that limits min / max values), and now you can state certain conditions - error handling is not required. Or, the user may enter the garbage, and you expect this to happen and should handle it. One or the other - there is nothing exceptional.

Throwing an exception allows me to pinpoint exactly what was wrong with StringValueTooLong or either IntegerValueTooLow or InvalidDateValue or something else. Why is this considered wrong?

I find this closer to evil. You can define the abstract interface ErrorProvider or return a complex object that represents an error, not simple code. There are many options for reporting errors. Using exceptions because they are convenient is wrong . I feel dirty, just writing this paragraph.

Consider making an exception a hope. The last chance. Praying. Verifying user input should not lead to any of these conditions.

+2
Jan 04 '09 at 8:52
source share

Another vote against exception handling for things that are not exceptions!

+2
Jan 04 '09 at 9:11
source share

In general, libraries throw exceptions and customers catch them and do something clever 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 usually don't have to worry about them. So what if the check requires an additional 100 ms to run? The user does not notice this.

In a sense, this is a difficult challenge. On the one hand, you may not want to collapse your entire application because the user has entered an additional digit in the text field of the zip code and you forgot to handle the exception. On the other hand, the “fail early, fail” approach ensures that errors are detected and corrected quickly and save your precious database. In general, I think most frameworks recommend that you do not use exception handling to check for user interface errors, and some, such as .NET Windows Forms, provide good ways to do this (ErrorProviders events and checks) without exception.

+1
Jan 04 '09 at 6:40
source share

Exceptions should not be used to validate input, since exceptions should not only be used in exceptional circumstances (which, as indicated, is incorrectly entered by the user), but they generate exceptional code (not in a brilliant sense).

The problem with exceptions in most languages ​​is that they change the rules of the program flow, which is great in really exceptional circumstances when it is not always possible to determine what the actual thread should be, and therefore just throw an exception and get however when you know what there must be a stream, you must create this stream (in the case shown, this would raise a message to the user telling them to re-enter some information).

Exceptions were truly excessive in the application that I work on a daily basis, and even when the user entered the wrong password when logging in, which, by your logic, will be the result of an exception, because this is not what the application wants. However, when a process has one of two results that are right or wrong, I don’t think we can say that the wrong one, no matter how wrong, is exceptional.

One of the main problems that I encountered while working with this code is trying to follow the logic of the code without deep involvement in the debugger. Although debuggers are great, it should be possible to add logic to what happens when a user enters an invalid password without having to run it.

Storing exceptions for truly exceptional execution is not just wrong. In the case when I emphasized that your password is incorrect, it is not exclusive, but you cannot contact the domain server!

+1
Jan 04 '09 at 13:45
source share

When I see exceptions thrown for validation errors, I often see that a method throwing an exception does a lot of checking right away. eg.

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 rather fragile and difficult to maintain as rules accumulate over months and years. I usually prefer to break my checks into smaller methods that bools return. This makes it easy to configure 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 already mentioned, returning a struct / object error containing error information is a great idea. The most obvious benefit is that you can collect them and display all the error messages to the user at the same time, instead of forcing them to play with Whack-A-Mole with validation.

+1
Jan 27 '09 at 17:49
source share

I used a combination of both solutions: for each verification function, I pass a record in which I fill in the verification status (error code). at the end of the function, if there is a validation error, I throw an exception, so I do not throw an exception for each field, but only once. I also took advantage of throwing an exception to stop execution, because I do not want the execution to continue when the data is invalid.

eg

 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 you rely only on a logical value, the developer using my function should consider this:

 if not Validate() then DoNotContinue(); 

but he can forget and only call Validate () (I know that he should not, but maybe he can).

therefore, in the above code, I got two advantages: 1 - only one exception in the check function. A 2 exception, even not displayed, will stop execution and appear during testing.

+1
May 15, '13 at 10:40
source share

8 years later, and I faced the same dilemma trying to apply the CQS pattern. I'm on the side that checking input can throw an exception, but with an added restriction. If any input fails, you need to throw an ONE exception: ValidationException, BrokenRuleException, etc. Do not drop a bunch of different types, as they cannot be dealt with. Thus, you get a list of all violated rules in one place. You create one class that is responsible for performing validation (SRP) and throws an exception if at least one rule is violated. Thus, you are dealing with one situation with one catch, and you know that you are good. You can handle this script no matter what code is invoked. This leaves all the code downstream much cleaner since you know that it is in the correct state or it would not get there.

For me, getting invalid data from a user is not what you usually expect. (If each user sends you invalid data for the first time, I would look at your user interface.) Any data that prevents you from processing the true intent, whether it is a user or a source of resources elsewhere, should interrupt processing. How could it be otherwise than throwing an ArgumentNullException from one piece of data if it was entered by the user, and this is a field in the class that says it is needed.

Of course, at first you can perform validation and write the same template code for each separate command, but I think this is a nightmare for maintenance than the trap of incorrect user input in one place at the top, which is processed equally regardless of (Less code!) A performance hit will only occur if the user returns incorrect data, which is not so often the case (or you have a bad interface). In any case, all the rules on the client side should be rewritten on the server, so you can just write them once, make an AJAX call, and <Delay of 500 ms will save you a ton of encoding time (only 1 place to put all your checking logic).

Also, although you can do some neat validation using ASP.NET out of the box, if you want to reuse the validation logic in other user interfaces, you won’t be able to do so since it was baked into ASP.NET. You would be better off creating something below and processing it above, regardless of the user interface used. (My 2 cents, at least.)

+1
Sep 19 '17 at 17:42 on
source share

I agree with Mitch 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 never tried to do tests, but it would be interesting to compare performance between words: if / else vs try / catch.

0
Jan 04 '09 at 6:32
source share

One problem with using exceptions is the tendency to detect only one problem at a time. The user corrects this and resubmits, only to find another problem! An interface that returns a list of issues that need to be resolved is much friendlier (although it can be wrapped in an exception).

0
Jan 04 '09 at 11:47
source share



All Articles