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.
<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.
This is a linguistic pov( point of view) on the matter.
It probably comes down to the expectations one takes about the code that is created.
However,
.
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?
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.
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:
Any other condition is not an error and should not be reported as an error.
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.
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.
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...