"Exception" as an English word
An unusual, remarkable occurrence. A low-probability occurrence. e.g.
Yes,
people do occasionally survive falling out of an aeroplane without a parachute, but that's the exception
rather than the rule.
Something that is not usually done, a bending of the rules, usually in someone's favour. e.g.
You told me again that you
preferred handsome men, but for me you would make an exception.
See also exceptional, which unless explicitly stated as exceptionally bad,
has the connotation of good, above average. e.g.
The intensive school was a
place for exceptional students. Exceptionally good
It was a wonderful, exceptional day. Exceptionally good
I have seen many decaying ruins, and this one is exceptionally decayed. Exceptionally decayed.
"To take exception to" is a formal, rather Victorian English phrase indicating that you feel insulted, that the utterance was beyond what is acceptable, e.g. "Sir, I take exception to your remarks concerning my mother's sexual practices. I challenge you to a duel."
"Exception" as programming term
yes, this is the main aim of my writeup
An exception is a
procedural programming language construct designed to deal with unusual or
error
conditions. Exceptions in the
programming sense are usually bad. e.g.
The
program threw an exception and crashed.
An exception can be seen as a goto in disguise. While this is true, it is
worth bearing in mind that all flow of control statements, if then else blocks, for loops, while loops, case etc. are all just gotos in disguise. All of them are improvements over using raw unstructured gotos, which are considered harmful for general use, and are unnecessary in almost all cases if you have structured replacements for them. Exceptions are no different, and are well worth using instead of trying to inspect the return value of every function that you call. Bruce Eckel explains:
If you were thorough enough to check for error every time you called a method, your code would turn into an unreadable nightmare.
The word "exception" is meant in the sense of "I take exception to that." At the point where the problem occurs you might not know what to do with it, but you know that you can't just continue on merrily, you must stop and somebody, somewhere, must figure out what to do.
.. they clean up error handing code. Instead of checking for a particular error and dealing with it in multiple places in your program, you no longer need to check at the method call ... you need to handle the problem at only one place, the exception handler
- from Thinking in Java, chapter 10 "error handling with exceptions" by Bruce Eckel.
An exception is thrown when an error occurs. Normal program flow is
interrupted, and control passes to the nearest enclosing exception handler, then
normal flow of control resumes. An exception is thrown due to the code explicitly doing so, or due to an interrupt from the operating system.
If this sounds odd and hard to grasp, then look at the examples first.
Since the popularity of Exceptions has come about after the popularity of
Object-Oriented programming, in most languages the exception is some kind of Object,
which can be queried as to its type and properties.
I will do some examples in a programming language that I use, Delphi. Delphi's
exception model is quite close to that of Python and C#. Java uses a substantially similar model, with the following minor differences:
- Java's catch keyword, with a different syntax, is used instead of except to catch and handle exceptions.
- All java methods must declare the exceptions that they may throw. When calling a method, the caller method must either catch all exceptions that the callee throws, or else must in turn declare them in it's own throws list. This is enforced by the compiler.
Your mileage may vary in other languages. Anyway, here are the Delphi code examples:
// a function that crashes, but the program will recover
function ArithmeticException: Double;
var
MyZero: Double;
begin
MyZero := 0;
Result := 10 / MyZero; // bang! - an exception will be thrown!!!
ShowMessage('You will not see this');
end;
procedure TryIt;
begin
try
ArithmeticException;
except
ShowMessage('Bang');
end;
end;
What happens when TryIt is called? At the division by zero, an exception is thrown.
The normal flow of execution stops, the stack is unwound until the nearest
enclosing try-except block is found. In this case it's not far away. The result
of calling TryIt is simply the message "Bang".
Finally blocks
The other form of exception handling, the try..finally block is used to
ensure that a piece of code is run no matter what, even if an exception is
thrown. This is usually used to ensure that allocated resources are freed.
For instance, if your code reads:
function ThisMayFail: Double;
var
lcSomeObj: TBigExpensiveObject;
begin
lcSomeObj := TBigExpensiveObject.Create;
lcSomeObj.SomeRiskyOperation;
lcSomeObj.SomeRiskyOperation;
Result := lcSomeObj.GetResultValueFromTheNetherDepths;
lcSomeObj.Free;
end;
If an exception is thrown during some risky operation, the object will never
be freed, and memory will leak. The following code is better:
function ThisMayFail: Double;
var
lcSomeObj: TBigExpensiveObject;
begin
lcSomeObj := TBigExpensiveObject.Create;
try
lcSomeObj.SomeRiskyOperation;
lcSomeObj.SomeRiskyOperation;
Result := lcSomeObj.GetResultValueFromTheNetherDepths;
finally
lcSomeObj.Free;
end;
end;
Now you are guaranteed that in normal execution, or even if an exception is
thrown, in fact always (barring a catastrophe such as a power failure, OS crash or the user
forcibly killing the entire program, in which case the memory leak won't matter)
the object will be freed. This will happen either in the normal sequence of statements, or on the way out while throwing an exception.
Advanced try..except:
There are several common variations on the try..except block:
You can manually raise an exception if you think it is warranted.
if pObject = nil then
Raise TMyException.Create('Nil pointer in someproc');
This also demonstrates that you can make your own subclasses of Exception, and test for them as shown in examples below.
You can squash exceptions.
procedure TryIt;
begin
try
ArithmeticException;
except
// on error, do nothing
end;
end;
This style is one of my pet hates. Try-except blocks are not a substitute for
good code or debugging. This is not error-free code, this is bad code that lies about its errors.
Errors should be reported so that they can be fixed, for e.g.
procedure TryIt;
begin
try
ArithmeticException;
except
on E: Exception
do
ShowMessage('Failed ArithmeticException with error ' + E.ClassName + ': ' + E.Message);
end;
end;
Which produces a nice error message "Failed ArithmeticException with error
EZeroDivide: Floating point division by zero". If a dialog box is not appropriate for your program (perhaps it is a server task that runs unattended and must keep running) then log the error and carry on. Just don't ignore it.
This also illustrates that Exceptions are objects.
You can be selective about which exception objects you catch, based on their type (all
Exceptions are of type Exception, or one of its sublasses). this is also good
practice - you don't want to tell the user that the text that they entered
cannot be converted to a string when actually the error was that the OS has run
out of memory:
procedure TryIt;
begin
try
ArithmeticException;
except
on E: EMathError
do
ShowMessage('Failed with a math error ' + E.ClassName + ': ' + E.Message)
else
Raise;
end;
end;
In this case, EMathError is a base class for EZeroDivide
and all other things that can go wrong with numbers. All other errors will be
passed on to the next enclosing try..except block. If none is found, then the
default handler which encloses the entire program will be invoked and show you a
nasty dialog box.