Recent Changes - Search:

About

Users

Developers

edit SideBar

DesignExceptions

t is better to list the guidelines 1] that we will pursue while designing exception hierarchy of our system.

  1. If an abnormal condition occurs during the process of any of the methods in the system, an Exception will be thrown.

  1. Avoid using exceptions to indicate conditions that can reasonably be expected as part of the normal functioning of the method.

  1. Define or choose an already existing exception class for each kind of abnormal condition that may cause your method to throw an exception.

  1. Due to the persistency, unchecked exceptions are ignored for now. That is to say, all exceptions thrown (or, therefore specified) by the methods will be checked exceptions for now.

From 1 above, First of all, if we analyze possible exceptions that system can generate, we can come up with a classification, which makes things easier. Nearly every package in the system (see packaging information?) consists of two basic operations; Formation and Service.

Formation refers to the processes in which instances of components (Calendar, Property, etc.) are formed via parsing files, which are generally pointed by URLs. In fact, initializing components consists further sub-elements. For example; parsing XML files, trying to load dynamic classes, etc.So, any abnormal conditions caused during these processes will be referred as FormationExceptions.

Service refers to processes in which components provide unique behaviors via their methods. As in Formation, this operation also consists of sub-elements. For example; dynamically loaded method calls, component search, update, remove method calls, etc. So, any abnormal conditions caused during these processes will be referred as ServiceExceptions.

From 2 above, A method is certainly allowed to return null or 0 when it can not find a component or find 0 number of components. This is generally true for parsing APIs, and exceptions are detected and thrown in higher levels.

From 3 above, It would be better to form or use an existing exception class for each kind of abnormal condition that may cause an exception to be thrown. So, a basic hierarchical exception structure (such as explained above) might obviously be specialized by adding leaf or node exceptions.

From 4 above, If we allow unchecked exceptions, in which a user does not have to be concerned, program will exit abruptly, therefore loosing all previous successfully loaded components (CalendricSystems, Calendars, etc.). This is due to persistency lack of the system.

Now let's look at Exception Hierarchy Design of the system under above circumstances. General hierarchy tree will look like;

(X refers to a component name, such as; Calendar, CalendricSystem, etc.)

According to above hierarchy other components will look like (A bold item means it can be further specialized under its node);

Calendar

Property

Field

CalendricSystem

TemporalDataTypes

And obviously all these Exceptions will be under a tauzamanException root node.

The main idea is that, a parent component will throw its Exceptions, no matter what other components throw when parent calls them and an abnormal situation occurs. For example; When forming a CalendricSystem via a URL, it does not give much understanding to user if PropertyFormationException is thrown. Instead a CalendricSystemFormationException is thrown embellished with information from PropertyFormationException.

According to all above ideas, here are two alternatives to Exception Handling of tauzaman;

1. see Design 1. Advantages of this design are:

  • Any kind of component related exception can be caught by just writing, where X corresponds to focused component;
     try{...}
     catch(XException e){...}
  • It reflects the package structure?. And by this design, it is convenient to place exceptions into their packages since hierarchy conforms to package design very well.
  • It allows exception chaining without any effort.
Letters in circles in the Design 1 correspond to priority on exception chaining (how a component is assigned a letter is decided by that component's relations with other components); \\ L corresponds to Low Level Exception.
M corresponds to Medium Level Exception.
H corresponds to High Level Exception.

2. see Design 2

  • Any kind of behavior exception can be caught by just writing, where X corresponds to focused component;
      try{...}
      catch(tauzamanXException e){...}
  • Hard to employ exception chaining. (not exactly true)

Design 1 is chosen to be implemented.

Exceptions on Registration Process
Registration Exceptions for the system added later. Here is the design decisions and rationale for them; We could possibly from a RegistrationException class and include every specific message inside it. However, this is not what we intended to do form the beginning, since any exception can also be caught by catching CalendricSystemException anyway. So, to be specific about exceptions, which also clears the try and catch code, we specialized each individual and meaningful exceptions. There were mainly three options; one of them extending new exceptions under the branch of CalendricSystemException, second, we could extend it under the branch of CalendricSystemServiceException and the last one is to extend it under the branch of tauzamanException as an individual exception. Not to add to many branches, which makes design and implementation hard to handle, first option is excluded, and last option seems to be abstract and violates Service and Formation exception understanding. The fact that all registration processes involve with Calendric Systems made us to choose second option. (see design issues related to user registration)

Exception Chaining
For precise back tracing of exceptions, all levels of (including Low Level ones) Exceptions will include a cause throwable object in their constructors along with a String message, which consists of the detailed explanation of the error. The reason even the Low Level Exceptions have causes in their constructors is that, there is in fact one lower level of exceptions, namely Lowest Level Exceptions, which are produced by Java itself and not dependent to our system. For example; MalformedURLException, Exceptions of ClassLoader and XML Parser classes. As a design decision, we don't want to throw these Exceptions to the user directly. These exceptions will be thrown by wrapping them inside more meaningful exceptions for the user. So, design criteria about exception chaining is;

  • Unless an exception is purely specialized, constructors will have (String message) and (String message, Throwable cause) arguments in their constructors. Specialized ones need not have cause. For example, MalformedURLException, NoSuchCalendarException, etc.
  • No trivial constructors.

Note: XFormationExceptions could have a specialized element called, ElementNotFoundException, which would also take just a String argument.

However, because of the following reasons, yet another exception hierarchy will be employed (idea will be still same);

  1. In design 1, for example, CalendarFormationException and CalendarServiceException extend CalendarException. However, I could not find any place, that may throw either CalendarFormationException or CalendarServiceException, and I have to catch CalendarException, in order to make code easier to handle. So, CalendarFormationException and CalendarServiceException don't share some states, they are completely different. This is same for other triples; Formation and Service Exceptions and their particular super class.
  2. Also, in design 1, assume a temporal data type is wanted to be formed, if any exceptions occurs during this process, system will throw TemporalDataTypeFormationException, which may include CalendricSystemServiceException to employ exception chaining if an abnormal condition occurs in CalendricSystem functionality. That makes design hierarchy in design 1 does not make sense.
  3. For above reasons we could use design 2, however, having TauZamanFormation and TauZamanService exception does not make sense for the reason listed in 2. In fact, the new design employed will be similar to design 2, but in a sense hierarchically less complex version.

3. see Design3.

  • Contains no extra information.
  • Exception Chaining is possible.
  • Captures all necessary exceptions and excludes conditions, which may not be regarded as abnormal. (Such as instead of throwing DuplicateCalendarException, return existing Calendar.)

References:

[1] Venners, B. Designing with Exceptions. On-line; http://www.javaworld.com/javaworld/jw-07-1998/jw-07-techniques.html

Edit - History - Print - Recent Changes - Search
Page last modified on April 17, 2009, at 08:22 AM