JSF Exception handling
ci Nov 14, 2006 10:51 AMHi!
We now have a pretty exception handling in Seam, but JSF exception are falling before the Seam gets the control, so I tried to use one light idea which was said in this forum some time ago.
public class CustomFacesServlet extends HttpServlet { ... public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { try { delegate.service(request, response); } catch (Throwable e) { if (!"".equals(errorPage)) { // rollback if needed rollbackTransactionIfNecessary(); // reconstruct the context for SeamRedirectorFilter HttpSession session = ((HttpServletRequest) request).getSession(true); PhaseId savedPhaseId = Lifecycle.getPhaseId(); Lifecycle.setPhaseId(PhaseId.INVOKE_APPLICATION); ServletRequest savedRequest = Lifecycle.getServletRequest(); Lifecycle.setServletRequest(request); Lifecycle.beginRequest(getServletContext(), session, request); Manager.instance().restoreConversation(request.getParameterMap()); Lifecycle.resumeConversation(session); Manager.instance().handleConversationPropagation(request.getParameterMap()); // put an exception into SESSION context Contexts.getSessionContext().set("exception", e); ((HttpServletResponse) response).sendRedirect( /* 113 row, see an exception below */ ((HttpServletRequest) request).getContextPath() + errorPage ); } } } ... }
Then, in web.xml:
<!--servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet--> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>qwerty.CustomFacesServlet</servlet-class> <init-param> <param-name>errorPage</param-name> <param-value>/error.seam</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.seam</url-pattern> </servlet-mapping>
But,
18:24:58,739 ERROR [SeamExceptionFilter] uncaught exception handled by Seam java.lang.NullPointerException at org.jboss.seam.servlet.SeamRedirectFilter.getViewId(SeamRedirectFilter.java:123) at org.jboss.seam.servlet.SeamRedirectFilter$1.sendRedirect(SeamRedirectFilter.java:87) at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:125) at qwerty.CustomFacesServlet.service(CustomFacesServlet.java:113) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:144) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.seam.servlet.SeamExceptionFilter.doFilter(SeamExceptionFilter.java:91) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:63) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178) at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175) at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105) at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527) at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112) at java.lang.Thread.run(Thread.java:595) 18:24:58,770 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception java.lang.NullPointerException at org.jboss.seam.servlet.SeamRedirectFilter.getViewId(SeamRedirectFilter.java:123) at org.jboss.seam.servlet.SeamRedirectFilter$1.sendRedirect(SeamRedirectFilter.java:87) at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:125) at qwerty.CustomFacesServlet.service(CustomFacesServlet.java:113) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:144) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.seam.servlet.SeamExceptionFilter.doFilter(SeamExceptionFilter.java:91) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:63) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178) at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175) at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105) at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527) at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112) at java.lang.Thread.run(Thread.java:595)
So, what if to change slightly the SeamRedirectFilter?
... public static String getViewId(String url) { if (FacesContext.getCurrentInstance() == null) return null; // added //for /seam/* style servlet mappings String pathInfo = FacesContext.getCurrentInstance().getExternalContext().getRequestPathInfo(); ...
Or did I miss something?