Michel Goldstein wrote:
Hi,

I have a very basic use case in which I need to access an external service
on a getter. However, this access might fail and cause an exception. When
the exception happens, I would like to redirect the user to an error page
that would explain that the service is unavailable and do not allow the user
to access that functionality until the service comes back up (so I can't
really just add to a message and render the message using the <h:message>
tag).

My first approach was in the lines of:

public TreeNode getData() {
    log.debug("Called getData");
    try {
        return resource.getDataAsTreeNode();
    } catch (Exception e) {
        log.error("Cannot access resource!");
        getUserMessages().addMessage("Cannot access a required resource.
Your access will be limited until the resource is available again.");
        FacesContext ctx = FacesContext.getCurrentInstance();
        ctx.getApplication
().getNavigationHandler().handleNavigation(ctx,"","error");
        return null;
    }
}

However, the problem is that the getter is being called twice during the
page processing and on the second time it throws an exception claiming that
the state is invalid during redirect. By the way, the error page navigation
rule in faces-config.xml uses the <redirect/> directive mostly to change the
URL on the browser so that the user can see that it is an error page.

My question then is a little bit more basic than this: what it looks like to
me is that I'm using the wrong pattern here to deal with exceptions. What
should be the right pattern?

Add ctx.renderResponse() at the end of your exception handling code. That'll tell JSF to jump straight to rendering the response when the current phase ends. I think that'll do the trick.

L.


Thank you,
Michel

Just for completeness sake, here is the stack trace of the error:

2006-02-22 13:01:10,485 44493 ERROR [TP-Processor3] [/ptd].[jsp] -
Servlet.service() for servlet jsp threw exception
javax.faces.el.EvaluationException: Cannot get value for expression '#{
test.data}'
        at org.apache.myfaces.el.ValueBindingImpl.getValue(
ValueBindingImpl.java:402)
        at org.apache.myfaces.custom.tree2.UITreeData.getValue(
UITreeData.java:264)
        at org.apache.myfaces.custom.tree2.HtmlTreeRenderer.encodeChildren(
HtmlTreeRenderer.java:173)
        at javax.faces.component.UIComponentBase.encodeChildren(
UIComponentBase.java:527)
        at javax.faces.webapp.UIComponentTag.encodeChildren(
UIComponentTag.java:474)
        at javax.faces.webapp.UIComponentTag.doEndTag(UIComponentTag.java
:361)
        at org.apache.jsp.exportViewResults_jsp._jspx_meth_t_tree2_0(
org.apache.jsp.exportViewResults_jsp:381)
        at org.apache.jsp.exportViewResults_jsp._jspx_meth_f_view_0(
org.apache.jsp.exportViewResults_jsp:176)
        at org.apache.jsp.exportViewResults_jsp._jspService(
org.apache.jsp.exportViewResults_jsp:100)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java
:97)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.apache.jasper.servlet.JspServletWrapper.service(
JspServletWrapper.java:322)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(
JspServlet.java:291)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
ApplicationFilterChain.java:252)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(
ApplicationFilterChain.java:173)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(
ApplicationDispatcher.java:672)
        at org.apache.catalina.core.ApplicationDispatcher.processRequest(
ApplicationDispatcher.java:463)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(
ApplicationDispatcher.java:398)
        at org.apache.catalina.core.ApplicationDispatcher.forward(
ApplicationDispatcher.java:301)
        at
org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(
ServletExternalContextImpl.java:416)
        at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(
JspViewHandlerImpl.java:234)
        at org.jenia.faces.template.handler.ViewHandler.renderView(
ViewHandler.java:74)
        at org.apache.myfaces.lifecycle.LifecycleImpl.render(
LifecycleImpl.java:372)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:109)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
ApplicationFilterChain.java:252)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(
ApplicationFilterChain.java:173)
        at org.apache.myfaces.component.html.util.ExtensionsFilter.doFilter(
ExtensionsFilter.java:129)
        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.apache.catalina.core.StandardHostValve.invoke(
StandardHostValve.java:126)
        at org.apache.catalina.valves.ErrorReportValve.invoke(
ErrorReportValve.java:105)
        at org.apache.catalina.core.StandardEngineValve.invoke(
StandardEngineValve.java:107)
        at org.apache.catalina.connector.CoyoteAdapter.service(
CoyoteAdapter.java:148)
        at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java
:307)
        at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java
:385)
        at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:748)
        at org.apache.jk.common.ChannelSocket.processConnection(
ChannelSocket.java:678)
        at org.apache.jk.common.SocketConnection.runIt(ChannelSocket.java
:871)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(
ThreadPool.java:684)
        at java.lang.Thread.run(Thread.java:534)
Caused by: javax.faces.el.EvaluationException: Exception getting value of
property data of base of type : test.TestBean
        at org.apache.myfaces.el.PropertyResolverImpl.getValue(
PropertyResolverImpl.java:96)
        at org.apache.myfaces.el.ELParserHelper$MyPropertySuffix.evaluate(
ELParserHelper.java:532)
        at org.apache.commons.el.ComplexValue.evaluate(ComplexValue.java
:145)
        at org.apache.myfaces.el.ValueBindingImpl.getValue(
ValueBindingImpl.java:383)
        ... 43 more
Caused by: javax.faces.el.EvaluationException: Bean: test.TestBean,
property: data
        at org.apache.myfaces.el.PropertyResolverImpl.getProperty(
PropertyResolverImpl.java:435)
        at org.apache.myfaces.el.PropertyResolverImpl.getValue(
PropertyResolverImpl.java:82)
        ... 46 more
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(
NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(
DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:324)
        at org.apache.myfaces.el.PropertyResolverImpl.getProperty(
PropertyResolverImpl.java:431)
        ... 47 more
Caused by: java.lang.IllegalStateException
        at org.apache.catalina.connector.ResponseFacade.sendRedirect(
ResponseFacade.java:423)
        at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(
HttpServletResponseWrapper.java:125)
        at
org.apache.myfaces.context.servlet.ServletExternalContextImpl.redirect(
ServletExternalContextImpl.java:490)
        at
org.apache.myfaces.application.NavigationHandlerImpl.handleNavigation(
NavigationHandlerImpl.java:131)
        at test.TestBean.getData(TestBean.java:74)
        ... 52 more
2006-02-22 13:01:10,489 44497 ERROR [TP-Processor3] [/ptd].[Faces Servlet] -
Servlet.service() for servlet Faces Servlet threw exception
javax.faces.FacesException: Cannot get value for expression '#{test.data}'
        at
org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(
ServletExternalContextImpl.java:422)
        at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(
JspViewHandlerImpl.java:234)
        at org.jenia.faces.template.handler.ViewHandler.renderView(
ViewHandler.java:74)
        at org.apache.myfaces.lifecycle.LifecycleImpl.render(
LifecycleImpl.java:372)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:109)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
ApplicationFilterChain.java:252)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(
ApplicationFilterChain.java:173)
        at org.apache.myfaces.component.html.util.ExtensionsFilter.doFilter(
ExtensionsFilter.java:129)
        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.apache.catalina.core.StandardHostValve.invoke(
StandardHostValve.java:126)
        at org.apache.catalina.valves.ErrorReportValve.invoke(
ErrorReportValve.java:105)
        at org.apache.catalina.core.StandardEngineValve.invoke(
StandardEngineValve.java:107)
        at org.apache.catalina.connector.CoyoteAdapter.service(
CoyoteAdapter.java:148)
        at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java
:307)
        at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java
:385)
        at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:748)
        at org.apache.jk.common.ChannelSocket.processConnection(
ChannelSocket.java:678)
        at org.apache.jk.common.SocketConnection.runIt(ChannelSocket.java
:871)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(
ThreadPool.java:684)
        at java.lang.Thread.run(Thread.java:534)
Caused by: org.apache.jasper.JasperException: Cannot get value for
expression '#{test.data}'
        at org.apache.jasper.servlet.JspServletWrapper.service(
JspServletWrapper.java:370)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(
JspServlet.java:291)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
ApplicationFilterChain.java:252)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(
ApplicationFilterChain.java:173)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(
ApplicationDispatcher.java:672)
        at org.apache.catalina.core.ApplicationDispatcher.processRequest(
ApplicationDispatcher.java:463)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(
ApplicationDispatcher.java:398)
        at org.apache.catalina.core.ApplicationDispatcher.forward(
ApplicationDispatcher.java:301)
        at
org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(
ServletExternalContextImpl.java:416)
        ... 22 more


Reply via email to