Professional Documents
Culture Documents
Exceptions Handling Constructs: Errno
Exceptions Handling Constructs: Errno
applications because they don't guarantee that runtime errors are actually caught
and handled
Runtime errors often occur when a low-level piece of code is executing. These low-
level functions cannot—and should not—try to handle the exception by themselves.
Instead, they should notify their caller of the error and let it decide how to handle it.
Chances are that somewhere up in the call chain, information about the exception
might be lost, thereby causing the application to mishandle it or ignore it altogether.
An exception can be a datatype such as int or a class object. The use of classes
allows you to define hierarchies of exceptions by means of derivation. Suppose you
have a function called alloc() that allocates a memory block of a requested size from
a private memory pool. alloc() detects anomalous runtime conditions such as an
invalid block size and throws an appropriate exception.
As a rule, pass exceptions by reference, not by value. Inside the catch block, you can
try to fix the problem or log the error and exit:
When an exception occurs, the normal flow of execution is interrupted and the
exception handling mechanism starts searching for a matching handler in the current
scope. If it can't find one, it pops the current function from the stack and the search
resumes in its caller. This process is called stack unwinding and it continues until a
matching handler is found or, if a matching handler doesn't exist, the program
terminates
xceptions are typically used to signal that something went wrong (e.g. a division by zero
occurred or a required file was not found). Exceptions are raised or thrown (initiated) by
either the hardware or the program itself by using a special command.
From the point of view of the author of a routine, raising an exception is a useful way to
signal that a routine could not execute normally. For example, when an input argument is
invalid (a zero denominator in division) or when a resource it relies on is unavailable
(like a missing file, or a hard disk error). In systems without exceptions, routines would
need to return some special error code
One of the problems with exception handling is knowing when and how to use it. In this
article, I will cover some of the best practices for exception handling. I will also
summarize the recent debate about the use of checked exceptions.
If not used correctly, exceptions can slow down your program, as it takes memory and
CPU power to create, throw, and catch exceptions. If overused,
Broadly speaking, there are three different situations that cause exceptions to be thrown:
• Checked exceptions: Exceptions that inherit from the Exception class are
checked exceptions. Client code has to handle the checked exceptions thrown by
the API, either in a catch clause or by forwarding it outward with the throws
clause.
• Unchecked exceptions: RuntimeException also extends from Exception.
However, all of the exceptions that inherit from RuntimeException get special
treatment. There is no requirement for the client code to deal with them, and
hence they are called unchecked exceptions.
This is a requirement; if you have one or more catch blocks, they must
immediately follow the try block. Additionally, the catch blocks must all
follow
each other, without any other statements or blocks in between. Also, the
order in which
the catch blocks appear matters, as we’ll see a little later.
try {
getTheFileFromOverNetwork
readFromTheFileAndPopulateTable
}
catch(CantGetFileFromNetwork) {
useLocalFileInstead
}
Try and catch provide a terrific mechanism for trapping and handling
exceptions,
but we are left with the problem of how to clean up after ourselves. Because
execution
transfers out of the try block as soon as an exception is thrown, we can’t put
our
cleanup code at the bottom of the try block and expect it to be executed if
an
exception occurs. Almost as bad an idea would be placing our cleanup code
in the
catch blocks.
A finally block encloses code that is always executed at some point after
the
try block, whether an exception was thrown or not. Even if there is a return
statement
in the try block, the finally block executes right after the return statement!
This
is the right place to close your files, release your network sockets, and
perform any
other cleanup your code requires. If the try block executes with no
exceptions, the
finally block is executed immediately after the try block completes. If
there
was an exception thrown, the finally block executes immediately after the
proper
catch block completes.
finally always runs ! OK, we’ll have to refine that a little, but for now,
start burning in the idea that finally always runs. If an exception is thrown,
finally runs.
If an exception is not thrown, finally runs. If the exception is caught, finally
runs. If
the exception is not caught, finally runs.
finally clauses are not required. If you don’t write one, your code will
compile
and run just fine.