Discussions

EJB design: Exception Handling Patterns for EJB 1.1

  1. Exception Handling Patterns for EJB 1.1 (5 messages)

    Hello,
    I can't find any design patterns for Server Side (EJB/Servlet) exception Handling.
    The books I have, say to rethrow all RemoteException wrapped in EJBException. But if an EJB is another's EJB client, that EJB will catch RemoteException and wrapp it as well. So by the time the original(ie. SQLException) will get to the presentation layer, you will have a quite alot of nested exceptions. Is there a pattern that can address this gracefully.
    Thanks In Advance!
    ilya
  2. I was reading somewhere about a ChainedException pattern (I believe it was in Javaworld). In this "pattern" (?), you would create a ChainedException subclass for each of your business exceptions. The ChainedException stores a ChainedException internally thus storing the entire chain of exception. A method is provide to retrieve the entire chain as an array or something.

    Search on the Javaworld site & see if it helps.
    --Das
  3. My practice, briefly, is this:

    - My EJBs always throw RuntimeException subclasses, because I always want to automatically roll back the transaction on an error. These get wrapped in EJBExceptions (or is it RemoteExceptions?)

    - I have a facade class for every EJB which hides the JNDI lookup of home interfaces and the creation of the SLSB from clients. This contains methods which look like:

    public AuthToken login(String user, String password)
    {
     try
     {
      return _remote.login(user, password);
     }
     catch (Exception t)
     {
      throw EJBUtil.unwrapException(t);
     }
    }

    The unwrapException() function contains code like:

    while ((e instanceof RemoteException)||(e instanceof EJBException))
    {
     if (e instanceof RemoteException)
     {
      if (((RemoteException)e).detail!=null)
      {
       e = ((RemoteException)e).detail;
      }
      else
       break;
     }
     else if (e instanceof EJBException)
     {
      if (((EJBException)e).getCausedByException()!=null)
       e = ((EJBException)e).getCausedByException();
      else
       break;
     }
    }
  4. Hi,
    I hate this wrappedexception pattern because, as you say, by the time your exception finally reaches someone who cares, they will have a hard time finding the original excetion. Instead I do the following. Always log an exception (like SQLException) at the source. Provide a usefull log statement capturing as much state as possible. My ejb methods can throw a SystemException or a subclass of a BusinessException. The SystemException indicates that the something BAD happened, eg. the database connection was lost or whatever. The BusinessException indicates that a business rule was vioaled, but the client application should be able to do something about it. At least show a good error message.

    Cheers,
    Mikkel
  5. I designed a set of 'message' codes which are specific to the business workflow.
    Now even if it is a chained("nested") exception u can always get the 'message' code where u are catching the thrown Runtime exception.
    Now a singleton reads and caches the MessageCatalog,which stores the key value pair of messages, at start up.

    I would term this as a "pattern".


  6. For the sake of being argumentative...

    The 'problem' with logging errors at source in a multi-layer system is that the layer where they occur isn't necessarily able to determine whether or not the exception is a true error condition, or whether it will be caught by an outer layer.

    The option I prefer is to maintain a single reference to the original exception and scrap the rest - the stack trace will be complete, in any case.

    The outer exception will then form part of the contract between the current layer and its clients and the inner exception will be used only by an exception handler.