@Override
 public boolean isCustomizedFor(final Throwable t) {
   if (t instanceof JspException) {
     final JspException j = (JspException) t;
     if (j.getRootCause() != null) {
       return isCustomizedFor(j.getRootCause());
     }
   }
   if (t instanceof ServletException) {
     final ServletException s = (ServletException) t;
     if (s.getRootCause() != null) {
       return isCustomizedFor(s.getRootCause());
     }
   }
   return exceptionClass.isAssignableFrom(t.getClass());
 }
  // javax.portlet.PortletRequestDispatcher implementation --------------------------------------
  public void include(RenderRequest request, RenderResponse response)
      throws PortletException, java.io.IOException {

    try {
      this.requestDispatcher.include(getServletRequest(request), getServletResponse(request));
    } catch (java.io.IOException e) {
      throw e;
    } catch (javax.servlet.ServletException e) {
      if (e.getRootCause() != null) {
        throw new PortletException(e.getRootCause());
      } else {
        throw new PortletException(e);
      }
    } finally {

    }
  }
  public int doStartTag() throws JspException {
    try {
      HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
      ModuleContext context = (ModuleContext) request.getSession().getAttribute("context");

      String viewObject = request.getParameter("viewObject");
      viewObject = (viewObject == null || viewObject.equals("")) ? "xava_view" : viewObject;
      View view = (View) context.get(request, viewObject);

      MetaReference metaReference = view.getMetaReference(reference).cloneMetaReference();
      metaReference.setName(reference);
      String prefix = request.getParameter("propertyPrefix");
      prefix = prefix == null ? "" : prefix;
      String application = request.getParameter("application");
      String module = request.getParameter("module");
      String referenceKey = Ids.decorate(application, module, prefix + reference);
      request.setAttribute(referenceKey, metaReference);
      String editorURL =
          "reference.jsp?referenceKey="
              + referenceKey
              + "&onlyEditor=true&frame=false&composite=false&descriptionsList=true";
      String editorPrefix = Module.isPortlet() ? "/WEB-INF/jsp/xava/" : "/xava/";
      try {
        pageContext.include(editorPrefix + editorURL);
      } catch (ServletException ex) {
        Throwable cause = ex.getRootCause() == null ? ex : ex.getRootCause();
        log.error(cause.getMessage(), cause);
        pageContext.include(editorPrefix + "editors/notAvailableEditor.jsp");
      } catch (Exception ex) {
        log.error(ex.getMessage(), ex);
        pageContext.include(editorPrefix + "editors/notAvailableEditor.jsp");
      }
    } catch (Exception ex) {
      log.error(ex.getMessage(), ex);
      throw new JspException(XavaResources.getString("descriptionsList_tag_error", reference));
    }
    return SKIP_BODY;
  }
Example #4
0
  @Override
  public void render(PageContext pageContext) throws JspException {
    try {
      if (UtilJ2eeCompat.doFlushOnRender(pageContext.getServletContext())) {
        pageContext.getOut().flush();
      }
      render(
          (HttpServletRequest) pageContext.getRequest(),
          (HttpServletResponse) pageContext.getResponse());
    } catch (java.io.IOException e) {
      Debug.logError(e, "Error rendering section: ", module);
      if (UtilJ2eeCompat.useNestedJspException(pageContext.getServletContext()))
        throw new JspException(e);
      else throw new JspException(e.toString());
    } catch (ServletException e) {
      Throwable throwable = e.getRootCause() != null ? e.getRootCause() : e;

      Debug.logError(throwable, "Error rendering section: ", module);
      if (UtilJ2eeCompat.useNestedJspException(pageContext.getServletContext()))
        throw new JspException(throwable);
      else throw new JspException(throwable.toString());
    }
  }
  @Override
  public void handleException(Context context, Throwable exception) {
    if (exception != null) {
      if ((exception instanceof ServletException)) {
        ServletException servletException = (ServletException) exception;
        logException(context, servletException.getRootCause());
      } else {
        logException(context, exception);
      }

      if (context != null) {
        includeErrorPage(context, exception);
      }
    } else {
      log.warn("Null exception passed to BasicExceptionHandler.  This should not happen.");
    }
  }
  /* ------------------------------------------------------------ */
  @Override
  public void initialize() throws Exception {
    super.initialize();

    if (_filter == null) {
      try {
        ServletContext context = _servletHandler.getServletContext();
        _filter =
            (context instanceof ServletContextHandler.Context)
                ? ((ServletContextHandler.Context) context).createFilter(getHeldClass())
                : getHeldClass().newInstance();
      } catch (ServletException se) {
        Throwable cause = se.getRootCause();
        if (cause instanceof InstantiationException) throw (InstantiationException) cause;
        if (cause instanceof IllegalAccessException) throw (IllegalAccessException) cause;
        throw se;
      }
    }

    _config = new Config();
    if (LOG.isDebugEnabled()) LOG.debug("Filter.init {}", _filter);
    _filter.init(_config);
  }
  /**
   * Adds more detailed logging for unhandled exceptions
   *
   * @see org.apache.struts.action.RequestProcessor#processException(HttpServletRequest,
   *     HttpServletResponse, Exception, ActionForm, ActionMapping)
   */
  @Override
  protected ActionForward processException(
      HttpServletRequest request,
      HttpServletResponse response,
      Exception exception,
      ActionForm form,
      ActionMapping mapping)
      throws IOException, ServletException {
    ActionForward actionForward = null;

    try {
      actionForward = super.processException(request, response, exception, form, mapping);
    } catch (IOException e) {
      logException(e);
      throw e;
    } catch (ServletException e) {
      // special case, to make OptimisticLockExceptions easier to read
      Throwable rootCause = e.getRootCause();
      if (rootCause instanceof OjbOperationException) {
        OjbOperationException ooe = (OjbOperationException) rootCause;

        Throwable subcause = ooe.getCause();
        if (subcause != null) {
          Object sourceObject = null;
          boolean optLockException = false;
          if (subcause instanceof javax.persistence.OptimisticLockException) {
            javax.persistence.OptimisticLockException ole =
                (javax.persistence.OptimisticLockException) subcause;
            sourceObject = ole.getEntity();
            optLockException = true;
          } else if (subcause instanceof OptimisticLockingFailureException) {
            OptimisticLockingFailureException ole = (OptimisticLockingFailureException) subcause;
            sourceObject = ole.getMessage();
            optLockException = true;
          } else {
            if (subcause
                .getClass()
                .getName()
                .equals("org.apache.ojb.broker.OptimisticLockException")) {
              try {
                sourceObject = PropertyUtils.getSimpleProperty(subcause, "sourceObject");
              } catch (Exception ex) {
                LOG.warn("Unable to retrieve source object from OJB OptimisticLockException", ex);
              }
              optLockException = true;
            }
          }
          if (optLockException) {
            StringBuilder message = new StringBuilder(e.getMessage());

            if (sourceObject != null) {
              if (sourceObject instanceof String) {
                message.append(" Embedded Message: ").append(sourceObject);
              } else {
                message.append(" (sourceObject is ");
                message.append(sourceObject.getClass().getName());
                message.append(")");
              }
            }

            e = new ServletException(message.toString(), rootCause);
          }
        }
      }

      logException(e);
      throw e;
    }
    return actionForward;
  }
Example #8
0
  private String acquireString() throws IOException, JspException {
    if (isAbsoluteUrl) {
      // for absolute URLs, delegate to our peer
      BufferedReader r = new BufferedReader(acquireReader());
      StringBuffer sb = new StringBuffer();
      int i;

      // under JIT, testing seems to show this simple loop is as fast
      // as any of the alternatives
      //
      // gmurray71 : putting in try/catch/finally block to make sure the
      // reader is closed to fix a bug with file descriptors being left open
      try {
        while ((i = r.read()) != -1) sb.append((char) i);
      } catch (IOException iox) {
        throw iox;
      } finally {
        r.close();
      }

      return sb.toString();
    } else {
      // handle relative URLs ourselves

      // URL is relative, so we must be an HTTP request
      if (!(pageContext.getRequest() instanceof HttpServletRequest
          && pageContext.getResponse() instanceof HttpServletResponse))
        throw new JspTagException(Resources.getMessage("IMPORT_REL_WITHOUT_HTTP"));

      // retrieve an appropriate ServletContext
      ServletContext c = null;
      String targetUrl = targetUrl();
      if (context != null) c = pageContext.getServletContext().getContext(context);
      else {
        c = pageContext.getServletContext();

        // normalize the URL if we have an HttpServletRequest
        if (!targetUrl.startsWith("/")) {
          String sp = ((HttpServletRequest) pageContext.getRequest()).getServletPath();
          targetUrl = sp.substring(0, sp.lastIndexOf('/')) + '/' + targetUrl;
        }
      }

      if (c == null) {
        throw new JspTagException(
            Resources.getMessage("IMPORT_REL_WITHOUT_DISPATCHER", context, targetUrl));
      }

      // from this context, get a dispatcher
      RequestDispatcher rd = c.getRequestDispatcher(stripSession(targetUrl));
      if (rd == null) throw new JspTagException(stripSession(targetUrl));

      // include the resource, using our custom wrapper
      ImportResponseWrapper irw = new ImportResponseWrapper(pageContext);

      // spec mandates specific error handling form include()
      try {
        rd.include(pageContext.getRequest(), irw);
      } catch (IOException ex) {
        throw new JspException(ex);
      } catch (RuntimeException ex) {
        throw new JspException(ex);
      } catch (ServletException ex) {
        Throwable rc = ex.getRootCause();
        if (rc == null) throw new JspException(ex);
        else throw new JspException(rc);
      }

      // disallow inappropriate response codes per JSTL spec
      if (irw.getStatus() < 200 || irw.getStatus() > 299) {
        throw new JspTagException(irw.getStatus() + " " + stripSession(targetUrl));
      }

      // recover the response String from our wrapper
      return irw.getString();
    }
  }
 protected void outputDefaultErrorPage(Context context, Throwable exception) {
   if (this.revealStackTrace) {
     context.print("<html>");
     context.print("<head><title>Internal error</title>");
     context.print("<style>");
     context.print("body { background-color: white; color: black; }");
     context.print("p { font-family: Arial, Helvetica, Sans-serif; font-size: 12px; }");
     context.print(
         "h2 { font-family: Arial, Helvetica, Sans-serif; font-size: 14px; font-weight: bold; }");
     context.print("pre { font-size: 9px; }");
     context.print("</style>");
     context.print("</head>");
     context.print("<body>");
     context.print("<!-- BasicExceptionHandler -->");
     context.print("<h2>Internal error</h2>");
     context.print("<p>An exception was caught by the application infrastructure:</p>");
     context.print("<p><pre>");
     context.print(convertStackTraceToString(exception));
     context.print("");
     context.print("</pre></p>");
     if ((exception instanceof ServletException)) {
       ServletException servletException = (ServletException) exception;
       if (servletException.getRootCause() != null) {
         context.print("<p>Root cause:</p>");
         context.print("<p><pre>");
         context.print(convertStackTraceToString(servletException.getRootCause()));
         context.print("");
         context.print("</pre></p>");
       } else {
         context.print("<p>No root cause provided.</p>");
       }
     }
     context.print("</body>");
     context.print("</html>");
   } else {
     context.print("<html><head>");
     context.print("<title>Server Error</title>");
     context.print("<style>");
     context.print("body { background-color: white; color: black; }");
     context.print(
         "p, div { color: white; font-family: Tahoma, Verdana, Arial, Helvetica, Sans-serif; font-size: 14px; }");
     context.print(".container { border: 8px solid #777777; width: 350px; }");
     context.print(
         ".banner { background: #D06060; color: white; font-weight: bold; padding: 4px }");
     context.print(".text { background: #777777; padding: 4px; }");
     context.print("</style>");
     context.print("</head><body>");
     context.print("<!-- BasicExceptionHandler -->");
     context.print("<div class=\"container\">");
     context.print("<div class=\"banner\">Please bear with us...</div>");
     context.print(
         "<div class=\"text\">We're sorry, our web site is not able to process your request correctly at this time.  Please try again at a later time.  If this situation persists, please get in touch with our customer service or technical support staff.</div>");
     context.print("</div>");
     context.print("<!--");
     context.print(convertStackTraceToString(exception));
     if ((exception instanceof ServletException)) {
       ServletException servletException = (ServletException) exception;
       context.print("Root cause:");
       context.print(convertStackTraceToString(servletException.getRootCause()));
     }
     context.print("-->");
     context.print("</body></html>");
   }
 }
Example #10
0
  /**
   * Serve the specified request, creating the corresponding response. After the first time a
   * particular servlet class is requested, it will be served directly (like any registered servlet)
   * because it will have been registered and mapped in our associated Context.
   *
   * @param request The servlet request we are processing
   * @param response The servlet response we are creating
   * @exception IOException if an input/output error occurs
   * @exception ServletException if a servlet-specified error occurs
   */
  public void serveRequest(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {

    // Disallow calling this servlet via a named dispatcher
    if (request.getAttribute(Globals.NAMED_DISPATCHER_ATTR) != null)
      throw new ServletException(sm.getString("invokerServlet.notNamed"));

    // Identify the input parameters and our "included" state
    String inRequestURI = null;
    String inServletPath = null;
    String inPathInfo = null;
    boolean included = (request.getAttribute(Globals.REQUEST_URI_ATTR) != null);

    if (included) {
      inRequestURI = (String) request.getAttribute(Globals.REQUEST_URI_ATTR);
      inServletPath = (String) request.getAttribute(Globals.SERVLET_PATH_ATTR);
      inPathInfo = (String) request.getAttribute(Globals.PATH_INFO_ATTR);
    } else {
      inRequestURI = request.getRequestURI();
      inServletPath = request.getServletPath();
      inPathInfo = request.getPathInfo();
    }
    if (debug >= 1) {
      log("included='" + included + "', requestURI='" + inRequestURI + "'");
      log("  servletPath='" + inServletPath + "', pathInfo='" + inPathInfo + "'");
    }

    // Make sure a servlet name or class name was specified
    if (inPathInfo == null) {
      if (debug >= 1) log("Invalid pathInfo '" + inPathInfo + "'");
      if (included)
        throw new ServletException(sm.getString("invokerServlet.invalidPath", inRequestURI));
      else {
        response.sendError(HttpServletResponse.SC_NOT_FOUND, inRequestURI);
        return;
      }
    }

    // Identify the outgoing servlet name or class, and outgoing path info
    String pathInfo = inPathInfo;
    String servletClass = pathInfo.substring(1);
    int slash = servletClass.indexOf('/');
    //        if (debug >= 2)
    //            log("  Calculating with servletClass='" + servletClass +
    //                "', pathInfo='" + pathInfo + "', slash=" + slash);
    if (slash >= 0) {
      pathInfo = servletClass.substring(slash);
      servletClass = servletClass.substring(0, slash);
    } else {
      pathInfo = "";
    }

    if (servletClass.startsWith("org.apache.catalina")) {
      response.sendError(HttpServletResponse.SC_NOT_FOUND, inRequestURI);
      return;
    }

    if (debug >= 1)
      log("Processing servlet '" + servletClass + "' with path info '" + pathInfo + "'");
    String name = "org.apache.catalina.INVOKER." + servletClass;
    String pattern = inServletPath + "/" + servletClass + "/*";
    Wrapper wrapper = null;

    // Synchronize to avoid race conditions when multiple requests
    // try to initialize the same servlet at the same time
    synchronized (this) {

      // Are we referencing an existing servlet class or name?
      wrapper = (Wrapper) context.findChild(servletClass);
      if (wrapper == null) wrapper = (Wrapper) context.findChild(name);
      if (wrapper != null) {
        if (debug >= 1)
          log(
              "Using wrapper for servlet '"
                  + wrapper.getName()
                  + "' with mapping '"
                  + pattern
                  + "'");
        context.addServletMapping(pattern, wrapper.getName());
      }

      // No, create a new wrapper for the specified servlet class
      else {

        if (debug >= 1)
          log("Creating wrapper for '" + servletClass + "' with mapping '" + pattern + "'");

        try {
          wrapper = context.createWrapper();
          wrapper.setName(name);
          wrapper.setLoadOnStartup(1);
          wrapper.setServletClass(servletClass);
          context.addChild(wrapper);
          context.addServletMapping(pattern, name);
        } catch (Throwable t) {
          log(sm.getString("invokerServlet.cannotCreate", inRequestURI), t);
          context.removeServletMapping(pattern);
          context.removeChild(wrapper);
          if (included)
            throw new ServletException(
                sm.getString("invokerServlet.cannotCreate", inRequestURI), t);
          else {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, inRequestURI);
            return;
          }
        }
      }
    }

    // Create a request wrapper to pass on to the invoked servlet
    InvokerHttpRequest wrequest = new InvokerHttpRequest(request);
    wrequest.setRequestURI(inRequestURI);
    StringBuffer sb = new StringBuffer(inServletPath);
    sb.append("/");
    sb.append(servletClass);
    wrequest.setServletPath(sb.toString());
    if ((pathInfo == null) || (pathInfo.length() < 1)) {
      wrequest.setPathInfo(null);
      wrequest.setPathTranslated(null);
    } else {
      wrequest.setPathInfo(pathInfo);
      wrequest.setPathTranslated(getServletContext().getRealPath(pathInfo));
    }

    // Allocate a servlet instance to perform this request
    Servlet instance = null;
    try {
      //            if (debug >= 2)
      //                log("  Allocating servlet instance");
      instance = wrapper.allocate();
    } catch (ServletException e) {
      log(sm.getString("invokerServlet.allocate", inRequestURI), e);
      context.removeServletMapping(pattern);
      context.removeChild(wrapper);
      Throwable rootCause = e.getRootCause();
      if (rootCause == null) rootCause = e;
      if (rootCause instanceof ClassNotFoundException) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND, inRequestURI);
        return;
      } else if (rootCause instanceof IOException) {
        throw (IOException) rootCause;
      } else if (rootCause instanceof RuntimeException) {
        throw (RuntimeException) rootCause;
      } else if (rootCause instanceof ServletException) {
        throw (ServletException) rootCause;
      } else {
        throw new ServletException(
            sm.getString("invokerServlet.allocate", inRequestURI), rootCause);
      }
    } catch (Throwable e) {
      log(sm.getString("invokerServlet.allocate", inRequestURI), e);
      context.removeServletMapping(pattern);
      context.removeChild(wrapper);
      throw new ServletException(sm.getString("invokerServlet.allocate", inRequestURI), e);
    }

    // After loading the wrapper, restore some of the fields when including
    if (included) {
      wrequest.setRequestURI(request.getRequestURI());
      wrequest.setPathInfo(request.getPathInfo());
      wrequest.setServletPath(request.getServletPath());
    }

    // Invoke the service() method of the allocated servlet
    try {
      String jspFile = wrapper.getJspFile();
      if (jspFile != null) request.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
      else request.removeAttribute(Globals.JSP_FILE_ATTR);
      request.setAttribute(Globals.INVOKED_ATTR, request.getServletPath());
      //            if (debug >= 2)
      //                log("  Calling service() method, jspFile=" +
      //                    jspFile);
      instance.service(wrequest, response);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
    } catch (IOException e) {
      //            if (debug >= 2)
      //                log("  service() method IOException", e);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
      try {
        wrapper.deallocate(instance);
      } catch (Throwable f) {;
      }
      throw e;
    } catch (UnavailableException e) {
      //            if (debug >= 2)
      //                log("  service() method UnavailableException", e);
      context.removeServletMapping(pattern);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
      try {
        wrapper.deallocate(instance);
      } catch (Throwable f) {;
      }
      throw e;
    } catch (ServletException e) {
      //            if (debug >= 2)
      //                log("  service() method ServletException", e);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
      try {
        wrapper.deallocate(instance);
      } catch (Throwable f) {;
      }
      throw e;
    } catch (RuntimeException e) {
      //            if (debug >= 2)
      //                log("  service() method RuntimeException", e);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
      try {
        wrapper.deallocate(instance);
      } catch (Throwable f) {;
      }
      throw e;
    } catch (Throwable e) {
      //            if (debug >= 2)
      //                log("  service() method Throwable", e);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
      try {
        wrapper.deallocate(instance);
      } catch (Throwable f) {;
      }
      throw new ServletException("Invoker service() exception", e);
    }

    // Deallocate the allocated servlet instance
    try {
      //            if (debug >= 2)
      //                log("  deallocate servlet instance");
      wrapper.deallocate(instance);
    } catch (ServletException e) {
      log(sm.getString("invokerServlet.deallocate", inRequestURI), e);
      throw e;
    } catch (Throwable e) {
      log(sm.getString("invokerServlet.deallocate", inRequestURI), e);
      throw new ServletException(sm.getString("invokerServlet.deallocate", inRequestURI), e);
    }
  }
Example #11
0
  /**
   * Creates a transaction from the provided request and response and then processes that
   * transaction by executing the target template.
   *
   * @param request the user's http request
   * @param response the user's http response
   */
  private boolean processTemplate(ApplicationRequest appRequest, ApplicationResponse appResponse)
      throws IOException {

    // check if redirect or erroring out
    if (appResponse.isRedirectOrError()) {
      return false;
    }

    // set initial content type and helper attributes
    appResponse.setContentType("text/html");
    appRequest.setAttribute(this.getClass().getName(), this);

    // lookup template
    Template template = (Template) appRequest.getTemplate();

    // process as resource if no template available
    if (template == null) {
      if (!processResource(appRequest, appResponse)) {
        appResponse.sendError(404);
        return false;
      }
      return true;
    }

    long endTime = 0L;
    long startTime = 0L;
    long contentLength = 0;

    TemplateStats templateStats = null;
    if (mInstrumentationEnabled) {
      templateStats = mTeaServletRequestStats.getStats(template.getName());
    }

    try {
      Object[] params = null;
      try {
        if (templateStats != null) {
          templateStats.incrementServicing();
        }

        // Fill in the parameters to pass to the template.
        Class<?>[] paramTypes = template.getParameterTypes();
        if (paramTypes.length == 0) {
          params = NO_PARAMS;
        } else {
          params = new Object[paramTypes.length];
          String[] paramNames = template.getParameterNames();
          for (int i = 0; i < paramNames.length; i++) {
            String paramName = paramNames[i];
            if (paramName == null) {
              continue;
            }

            Class<?> paramType = paramTypes[i];

            if (!paramType.isArray()) {
              String value = appRequest.getParameter(paramName);
              if (value == null || paramType == String.class) {
                params[i] = value;
              } else {
                params[i] = convertParameter(value, paramType);
              }
            } else {
              String[] values = appRequest.getParameterValues(paramName);
              if (values == null || paramType == String[].class) {
                params[i] = values;
              } else {
                paramType = paramType.getComponentType();
                Object converted = Array.newInstance(paramType, values.length);
                params[i] = converted;
                for (int j = 0; j < values.length; j++) {
                  Array.set(converted, j, convertParameter(values[j], paramType));
                }
              }
            }
          }
        }

        startTime = System.currentTimeMillis();
        try {
          try {
            appRequest.getTemplate().execute(appResponse.getHttpContext(), params);
          } catch (ContextCreationException cce) {
            // unwrap the inner exception
            throw (Exception) cce.getUndeclaredThrowable();
          }
        } catch (AbortTemplateException e) {
          if (DEBUG) {
            mLog.debug("Template execution aborted!");
            mLog.debug(e);
          }
        } catch (RuntimeException e) {
          if (getEngine().getTemplateSource().isExceptionGuardianEnabled()) {
            // Just log the error and use what the template wrote out.
            mLog.error(e);
          } else {
            throw new ServletException(e);
          }
        } catch (IOException e) {
          // TODO: shouldn't we be throwing this as a ServletException?
          //       otherwise its not logged to the TeaLog.
          throw e;
        } catch (ServletException e) {
          throw e;
        } catch (Exception e) {
          throw new ServletException(e);
        }
        // TODO: shouldn't we be catching errors and not just exceptions?
        //       otherwise its not logged to the TeaLog.
        finally {
          endTime = System.currentTimeMillis();
          if (appRequest instanceof TeaServletStats) {
            long duration = endTime - startTime;
            ((TeaServletStats) appRequest).setTemplateDuration(duration);
          }
        }

        if (DEBUG) {
          mLog.debug("Finished executing template");
        }
      } catch (ServletException e) {
        // Log exception
        StringBuffer msg = new StringBuffer();
        msg.append("Error processing request for ");
        msg.append(appRequest.getRequestURI());
        if (appRequest.getQueryString() != null) {
          msg.append('?');
          msg.append(appRequest.getQueryString());
        }
        mLog.error(msg.toString());

        Throwable t = e;
        while (t instanceof ServletException) {
          e = (ServletException) t;
          if (e.getRootCause() != null) {
            String message = e.getMessage();
            if (message != null && message.length() > 0) {
              mLog.error(message);
            }
            mLog.error(t = e.getRootCause());
          } else {
            mLog.error(e);
            break;
          }
        }

        // Internal server error unless header is already set
        if (!appResponse.isRedirectOrError()) {
          String displayMessage = e.getLocalizedMessage();
          if (displayMessage == null || displayMessage.length() == 0) {
            appResponse.sendError(ApplicationResponse.SC_INTERNAL_SERVER_ERROR);
          } else {
            appResponse.sendError(ApplicationResponse.SC_INTERNAL_SERVER_ERROR, displayMessage);
          }
        }
      }
      contentLength = appResponse.getResponseBuffer().getByteCount();
      appResponse.finish();
      if (templateStats != null) {
        templateStats.decrementServicing();
        templateStats.log(startTime, endTime, contentLength, params);
      }
    } catch (Exception e) {
      if (templateStats != null) {
        templateStats.decrementServicing();
      }
    }
    return true;
  }