cppannotations/yo/exceptions/emptythrow.yo
fbbrokken 6881bc3814 The trunk directory contains the latest version (6.4.0c) of the C++
Annotations. 

The branches and tags directory are empty, since I couldn't
svnadmin import a repostitory dump. Many earlier versions exist, though, and
if you want the full archive, just let me know and I'll send you the svnadmin
dump of my full C++ Annotations archive.

Frank B. Brokken <f.b.brokken@rug.nl>



git-svn-id: https://cppannotations.svn.sourceforge.net/svnroot/cppannotations/trunk@3 f6dd340e-d3f9-0310-b409-bdd246841980
2006-09-04 08:26:34 +00:00

97 lines
4.4 KiB
Text

Situations may occur in which it is required to inspect a thrown
exception. Then, depending on the nature of the received exception, the
program may continue its normal operation, or a serious event took place,
requiring a more drastic reaction by the program. In a server-client situation
the client may enter requests to the server into a queue. Every request placed
in the queue is normally answered by the server, telling the client that the
request was successfully completed, or that some sort of error has
occurred. Actually, the server may have died, and the client should be able to
discover this calamity, by not waiting indefinitely for the server to reply.
In this situation an intermediate i(exception handler) is called for. A thrown
exception is first inspected at the middle level. If possible it is processed
there. If it is not possible to process the exception at the middle level, it
is passed on, unaltered, to a more superficial level, where the really tough
exceptions are handled.
By placing an hi(throw: empty) em(empty) tt(throw) statement in the code
handling an exception the received exception is passed on to the next level
that might be able to process that particular type of exception.
In our server-client situation a function
verb(
initialExceptionHandler(char *exception)
)
could be designed to do so. The received message is inspected. If it's a
simple message it's processed, otherwise the exception is passed on to an
outer level. The implementation of tt(initialExceptionHandler()) shows the
empty tt(throw) statement:
verb(
void initialExceptionHandler(char *exception)
{
if (!plainMessage(exception))
throw;
handleTheMessage(exception);
}
)
As we will see below (section ref(EXCEPTIONCATCH)), the empty tt(throw)
statement passes on the exception received in a tt(catch)-block. Therefore, a
function like tt(initialExceptionHandler()) can be used for a variety of
thrown exceptions, as long as the argument used with
tt(initialExceptionHandler()) is compatible with the nature of the received
exception.
Does this sound intriguing? Then try to follow the next example, which jumps
slightly ahead to the topics covered in chapter ref(POLYMORPHISM). The next
example may be skipped, though, without loss of continuity.
We can now state that a i(basic exception handling) class can be constructed
from which specific exceptions are derived. Suppose we have a class
tt(Exception), containing a member function tt(ExceptionType
Exception::severity()). This member function tells us (little wonder!) the
severity of a thrown exception. It might be tt(Message, Warning, Mistake,
Error) or tt(Fatal). Furthermore, depending on the severity, a thrown
exception may contain less or more information, somehow processed by a
function tt(process()). In addition to this, all exceptions have a plain-text
producing member function, e.g., ti(toString()), telling us a bit more about
the nature of the generated exception.
Using i(polymorphism), tt(process()) can be made to behave differently,
depending on the nature of a thrown exception, when called through a basic
tt(Exception) pointer or reference.
In this case, a program may throw any of these five types of exceptions. Let's
assume that the tt(Message) and tt(Warning) exceptions are processable by our
tt(initialExceptionHandler()). Then its code would become:
verb(
void initialExceptionHandler(Exception const *e)
{
cout << e->toString() << endl; // show the plain-text information
if
(
e->severity() != ExceptionWarning
&&
e->severity() != ExceptionMessage
)
throw; // Pass on other types of Exceptions
e->process(); // Process a message or a warning
delete e;
}
)
Due to polymorphism (see chapter ref(POLYMORPHISM)), tt(e->process()) will
either process a tt(Message) or a tt(Warning). Thrown exceptions are generated
as follows:
verb(
throw new Message(<arguments>);
throw new Warning(<arguments>);
throw new Mistake(<arguments>);
throw new Error(<arguments>);
throw new Fatal(<arguments>);
)
All of these exceptions are processable by our
tt(initialExceptionHandler()), which may decide to pass exceptions upward for
further processing or to process exceptions itself. The polymorphic exception
class is developed further in section ref(POLYMORPHEXCEPTION).