tuscany-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From edward...@apache.org
Subject svn commit: r381603 - /incubator/tuscany/site/src/site/xdoc/exception_handling.html
Date Tue, 28 Feb 2006 09:29:08 GMT
Author: edwardsmj
Date: Tue Feb 28 01:29:06 2006
New Revision: 381603

URL: http://svn.apache.org/viewcvs?rev=381603&view=rev
Adding the new site layout, with src and target subtrees and POM and format compliant with

    incubator/tuscany/site/src/site/xdoc/exception_handling.html   (with props)

Added: incubator/tuscany/site/src/site/xdoc/exception_handling.html
URL: http://svn.apache.org/viewcvs/incubator/tuscany/site/src/site/xdoc/exception_handling.html?rev=381603&view=auto
--- incubator/tuscany/site/src/site/xdoc/exception_handling.html (added)
+++ incubator/tuscany/site/src/site/xdoc/exception_handling.html Tue Feb 28 01:29:06 2006
@@ -0,0 +1,158 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

        <title>Exception Handling Guidelines for The Java Runtime</title>
        <h1>Java Runtime Exception Policy</h1>
       <p> The key tenet of this exception policy is that exceptions should be designed
with an eye
+            toward what the catch clause would likely do with the exception. The three main
+            are: </p>
+            <li>Code Exception: Code can work around the discovered problem</li>
+            <li>User Exception: Problem to be remedied by a human (e.g. Administrator)</li>
+            <li>Assertion Exception: Problem remedied by human fixing a bug in the
+        </ul>
+        <h2>Code Exceptions</h2>
+        <p> These are exceptions where it is expected that some calling code may be
able to
+            completely handle the exception, without involvement of any user. In other words,
+            exception is of an alternate way of returning a value. There is a reasonable
chance that
+            calling code (maybe a couple levels up) will be able to catch the exception and
+            try again or try some other approach to accomplishing its job. Note that there
may be no
+            way of knowing whether the caller will be able to figure out a different approach
+            handling the situation. This is especially true in reusable utility code. In
+            cases, the exceptions should be considered to be code exceptions. The code that
+            the exception might just turn it into a different kind of exception.</p>
+        <h3>Implications</h3>
+        <p>In general, code exceptions should be checked exceptions. They should be
named based on
+            what happened, rather than based on who is throwing the exception. If the exception
+            well named, it should be possible for the exception to be present on signatures
+            several levels of a call stack and still make sense (e.g. ServiceUnavailableException).</p>
+        <p>There are some cases where code exceptions should not be checked exceptions.
If code
+            cannot reasonably be expected to recover from an exception, it should be unchecked,
+            Also, iIf a large fraction of the methods in the code would need to declare the
+            exception, then its declaration doesn't add much value and so it should be a
+            RuntimeException so it doesn't need to be declared. One example of this kind
+            exception might be a RetryException. This exception might occur on some kind
of resource
+            conflict where retrying the transaction is likely to solve it. Since it is solved
+            without human involvement it is still a "code exception". </p>
+        <h2>User Exceptions</h2>
+        <p> These are exceptions that signal a problem that will be handled by a person,
so the most
+            important component of the exception is the message, rather than the type of
+            exception. Unfortunately, the code that throws the original exception often will
+            have enough information to give a meaningful message to the user that has all
+            necessary context. The typical "user" in this situation is an administrator,
where a
+            stack traceback wouldn't be very helpful. Because of this, it is important that
code be
+            littered with try/catch blocks that do no more than add context to the exception
+            and then rethrow.</p>
+        <p>In a previous project this was done by having a base UserException class
that had an
+            array of messages, rather than just one message. For example, code that parses
an SCA
+            subsystem file might have a rethrow that just adds "While parsing the xyz subsystem
+            file". That is a message that could not be generated by the code that discovered
+            problem (say an XML parsing problem), so a combination of the original message
+            "Missing end tag") and the higher level message ("while parsing the xyz subsystem
+            are both necessary for know what happened. Naturally it can be any number of
+            deep.</p>
+        <p> The handling code for a user exception will somehow notify a user of the
message and
+            then possibly go on. There should be different kinds of exceptions when there
need to be
+            different ways of handling of the message or different ways to continue. Different
+            to report the error: In a server, user exceptions can often be divided according
+            fault: </p>
+        <ul>
+            <li>It's the fault of the client code that is sending the incoming message
(e.g. SOAP
+                faults).</li>
+            <li>It's the fault of the code or configuration that is handling the message.
+        </ul>
+        <p> If the problem is the fault of the client code, then the message needs
to be reported
+            back to the client code in a format appropriate for the client. If the problem
is the
+            fault of the server code or configuration, then only a vague "I've got a problem
+            message should be sent to the client and the real exception message should be
+            and/or sent to an administrator. Because of the two different ways of handling
+            problem, there should be different exception types. For example, ClientException
+            be used for exceptions that signal problems that are the client's fault. </p>
+        <p> The remaining user exceptions are typically problems with configuration
or the
+            environment. Some of them will be severe enough that the entire application needs
to be
+            brought down, while others could be handled by just logging the problem and going
+            This difference implies that there needs to be a different exception type. Advanced
+            Scenario: In the case of session-scoped services, the problem is likely to require
+            the instance of the service be put into an error state (like paused). This is
+            subsequent messages for the service have been sent on the assumption that the
+            message actually gets processed. If some configuration error prevents a session-scoped
+            service from handling a single message, all future (async) messages for that
+            instance should be queued up so they can be processed once the problem has been
solved. </p>
+        <h2>Assertion Exceptions</h2>
+        <p> Assertion exceptions are exceptions that result from a bug in Tuscany and
as such are
+            also intended to be solved by humans, but in this case the humans are us --are
+            developers of the SCA runtime. In these cases the message isn't nearly as important,
+            since the stack traceback provides valuable context. If an assertion exception
+            little can be known about the state of the server. If we wanted to be safe we
would say
+            that assertion exceptions always bring down the entire server. However, we could
play it
+            a little looser and say that assertion exceptions only bring down the application
+            which they are discovered. </p>
+        <h2>Guidelines</h2>
+        <p> The following are a set of guidelines based on the above exception philosophy:
+        <h4>1. Checked vs. unchecked exceptions</h4>
+        <p> Unchecked exceptions should be used when an error condition is not recoverable.
+            exceptions thrown by third party libraries that are not recoverable should be
wrapped in
+            unchecked exceptions rather than being propagated up the call stack. For example,
+            IOException raised when reading a file might be wrapped in an unchecked LoadException
+            containing the name of the file.
+            Unchecked must always be Javadoced and declared in the throws clause of a method.
+        <h4>2. Assertion exceptions should use the standard JDK assert facilities</h4>
+        <h4>3. Any exception thrown to user code must extend the appropriate Exception
as defined
+               by the specification. This will typically be a runtime Exception.</h4>
+        <h4>4. No other Exceptions should be thrown to user code. Each user API method
+               catch any internal exceptions and wrap them in the applicable Exception defined
+               by the specification. Internal exceptions must ultimately extend either TuscanyException
+               or TuscanyRuntimeException.
+        <h4>4. When possible, create clear package exception hierarchies</h4>
+        <p> In most cases, packages should have a clear exception hierarchy with abstract
+            checked and unchecked exceptions which more specific concrete exceptions extend.
+            Declaring the root package exceptions abstract avoids code throwing exceptions
which are
+            too general. Creating an exception hierarchy allows client code using a particular
+            package to choose the level of exception handling granularity (which in turn
+            the client code by avoiding unwieldy try..catch clauses). </p>
+        <h4> 5. Preserve all stack trace information and the original exception</h4>
+        <p> Exceptions must always preserve the stack trace and original exception
except under
+            special circumstances. When wrapping exceptions to propagate, never modify the
+            trace and always include the caught exception as the cause.</p>
+        <h4>6. Only include local information pertinent to the failure</h4>
+        <p> For I18N, contextual information stored in the Exception should not be
localized. It
+            should comprise only data pertaining to the cause, such as the name of the artifact
+            above, or a key that can be used by the top level exception handler. This is
+            because the locale used to render the exception may be completely different from
+            locale used by the code raising the exception. For example, an exception may
be thrown
+            on a system whose default locale is German, logged to the system log in English
+            displayed to the end user in French, Japanese, whatever their native language
is. </p>
+        <h4>7. For exceptions that require contextual information from various code
layers, either
+            wrap exceptions or create exceptions that can accept additional context as they
+            propagated up the call stack.</h4>
+        <p> If a failure requires information from multiple levels, e.g. “there
was an error setting
+            property X on component Y in module Z� do one of the following. If the initial
+            should be wrapped as it is propagated (e.g. the exception occurs at a library
+            add additional context information in the wrapping exception(s). If the initial
+            exception can be propagated, include methods for adding additional context information
+            as the exception is rethrown up the stack. For example, the previous failure
+            could result in the following exception handling strategy: </p>
+        <ul>
+            <li> A component property is configured with an invalid integer type</li>
+            <li> The property value parsing code attempts to load an integer value
using parseInt(),
+                resulting in a NumberFormatException</li>
+            <li> NumberFormatException is wrapped in an InvalidParameterException (IPE)
+                the name of the property.</li>
+            <li> IPE extends a more general ConfigException, which has setters for
adding additional
+                context information such as component and module names</li>
+            <li> As the IPE is thrown up the stack, the component and module parsers
+                additional context information.</li>
+            <li> The configuration loader then wraps the IPE in a ConfigLoadExeption
and provides
+                the source from which the configuration is being loaded.</li>
+            <li> The UI being used to load the configuration reports the error to the
user and
+                displays the appropriate contextual information</li>
+        </ul>
+        <h4>8. getMessage() must return unformatted context info. If the Exception
contains multiple
+               context fields they should be surrounded in square brackets and separated
by commas,
+               e.g. "[ property X, component Y, module Z ]"</h4>
+        <h4>9. Do not override the behaviour of Throwable.toString() and Throwable.printStackTrace()</h4>
+        <h4>10. The java.lang.Exception base class is Serializable so all subclasses
must provide
+                a serial UID. Any context fields must be Serializable and should be defined
in the
+                base java namespace for JDK1.4.</h4>
+        <h4>11. Exceptions that wrap other Exceptions should ensure that any wrapped
Exception can
+                be deserialized in a client environment. This may require providing a custom
+                writeObject method to extract any context information from the wrapped Exception
+                during serialization; at a minimum the message should be preserved.</h4>
+    </body>

Propchange: incubator/tuscany/site/src/site/xdoc/exception_handling.html
    svn:keywords = Rev,Date

View raw message