Save This Page
Home » tapestry-src-5.0.19 » org.apache.tapestry5.internal.services » [javadoc | source]
    1   package org.apache.tapestry5.internal.services;
    2   
    3   import org.apache.tapestry5.services;
    4   
    5   import java.io.IOException;
    6   
    7   /**
    8    * Filter for the {@link org.apache.tapestry5.services.RequestHandler} pipeline used to intercept and report
    9    * exceptions.
   10    */
   11   public class RequestErrorFilter implements RequestFilter
   12   {
   13       private final InternalRequestGlobals internalRequestGlobals;
   14       private final RequestExceptionHandler exceptionHandler;
   15   
   16       public RequestErrorFilter(InternalRequestGlobals internalRequestGlobals, RequestExceptionHandler exceptionHandler)
   17       {
   18           this.internalRequestGlobals = internalRequestGlobals;
   19           this.exceptionHandler = exceptionHandler;
   20       }
   21   
   22       public boolean service(Request request, Response response, RequestHandler handler) throws IOException
   23       {
   24           try
   25           {
   26               return handler.service(request, response);
   27           }
   28           catch (IOException ex)
   29           {
   30               // Pass it through.
   31               throw ex;
   32           }
   33           catch (Throwable ex)
   34           {
   35               // Most of the time, we've got exception linked up the kazoo ... but when ClassLoaders
   36               // get involved, things go screwy.  Exceptions when transforming classes can cause
   37               // a NoClassDefFoundError with no cause; here we're trying to link the cause back in.
   38               // TAPESTRY-2078
   39   
   40               Throwable exceptionToReport = attachNewCause(ex, internalRequestGlobals.getClassLoaderException());
   41   
   42               exceptionHandler.handleRequestException(exceptionToReport);
   43   
   44               // We assume a reponse has been sent and there's no need to handle the request
   45               // further.
   46   
   47               return true;
   48           }
   49       }
   50   
   51       private Throwable attachNewCause(Throwable exception, Throwable underlyingCause)
   52       {
   53           if (underlyingCause == null) return exception;
   54   
   55           Throwable current = exception;
   56   
   57           while (current != null)
   58           {
   59   
   60               if (current == underlyingCause) return exception;
   61   
   62               Throwable cause = current.getCause();
   63   
   64               // Often, exceptions report themselves as their own cause.
   65   
   66               if (current == cause) break;
   67   
   68               if (cause == null)
   69               {
   70   
   71                   try
   72                   {
   73                       current.initCause(underlyingCause);
   74   
   75                       return exception;
   76                   }
   77                   catch (IllegalStateException ex)
   78                   {
   79                       // TAPESTRY-2284: sometimes you just can't init the cause, and there's no way to
   80                       // find out without trying.
   81   
   82                   }
   83               }
   84   
   85               // Otherwise, continue working down the chain until we find a place where we can attach
   86   
   87               current = cause;
   88           }
   89   
   90           // Found no place to report the exeption, so report the underlying cause (and lose out
   91           // on all the other context).
   92   
   93           return underlyingCause;
   94       }
   95   }

Save This Page
Home » tapestry-src-5.0.19 » org.apache.tapestry5.internal.services » [javadoc | source]