-
1. Re: Handling Errors when usign JPDL Pageflow.
pmuir Oct 5, 2008 3:51 PM (in response to jnusaira)Once a transition has started in a pageflow, you're beyond the point returning to an old page IIRC. I guess you could file a feature request, and see if you can work out how to implement it...
-
2. Re: Handling Errors when usign JPDL Pageflow.
ahus1 Oct 5, 2008 9:04 PM (in response to jnusaira)I use an exception handler in (every) JPDL pageflow. Saves some information about the current (and previous) node.
<exception-handler exception-class="javax.el.ELException"> <action class="de.plusfinanzservice.common.bean.ExceptionAction" /> </exception-handler>
Later, an exception handler in pages.xml picks it up and repositions the JPDL pageflow.
<exception class="java.lang.Exception"> <redirect view-id="#{exceptionHandler.getViewId('/iss/error.jspx')}"> <message severity="error"> #{messages[exceptionHandler.getMessage(org.jboss.seam.handledException)]} </message> </redirect> </exception>
The code for the exception action.
In a jpdl pageflow with seam we usually use EL expressions, therefore all exceptions we get here are wrapped in an EL Exception. First we unwrap them.
We determine the source of the transition. If the source is a decision node (and not a page node), we will need to find the error handling page node. Our convention is to use a
failure
transition on every decision node to do exactly that. The data is saved on a new seam bean exception handler (see below).public class ExceptionAction implements ActionHandler { private static final long serialVersionUID = 1L; @Logger private Log log; /** * Handle jpdlException. For transitions we * @param executionContext context */ public void execute(ExecutionContext executionContext) { Throwable e = executionContext.getException(); if (e instanceof ELException && e.getCause() != null && e.getCause() instanceof Exception) { e = e.getCause(); } /* * if this is a transition, we memorize the source, throw an exception and * reposition the flow from within seam. */ Node source = executionContext.getTransitionSource(); if (source != null) { /* * if the source of the transition is a decision, handle the failure of * the transition like the failure of the decision. */ while (source instanceof Decision) { Decision d = (Decision) source; source = d.getLeavingTransition("failure").getTo(); } ExceptionHandler handler = (ExceptionHandler) Component .getInstance(ExceptionHandler.class); handler.setNode(source.getName()); throw new JpdlException("caught in transition", e); } else { BasicUtil.exceptionToMessage(log, e); } } }
The exception handler in pages.xml; the relevant code is:
if (node != null) { Pageflow.instance().reposition(node); retVal = Pageflow.instance().getPage().getViewId(); }
The complete code follows. It does a bit more; it tries to fit all exceptions and tries place the use on the last view in the conversation (when there is no current pageflow).
@Name("exceptionHandler") @Scope(ScopeType.EVENT) public class ExceptionHandler implements Serializable { private static final long serialVersionUID = 1L; private String node; /** * Get view id for error handling. * @param defaultErrorView default error view * @return view id to display error */ @Begin(join = true) public String getViewId(String defaultErrorView) { String retVal; HttpServletRequest request = (HttpServletRequest) FacesContext .getCurrentInstance().getExternalContext().getRequest(); if (request.getMethod().equals("GET")) { if (Conversation.instance().isNested()) { retVal = FacesManager.instance().getParentConversationViewId(); Conversation.instance().endAndRedirect(); } else { retVal = defaultErrorView; } } else if (Conversation.instance().getViewId() != null) { if (node != null) { Pageflow.instance().reposition(node); retVal = Pageflow.instance().getPage().getViewId(); } else { retVal = Conversation.instance().getViewId(); } Conversation.instance().setViewId(null); } else { Conversation.instance().end(); retVal = defaultErrorView; } /* * workaround for Bug http://jira.jboss.org/jira/browse/JBSEAM-2985 Please * remove when this bug is closed. */ if (Contexts.getPageContext() == null) { PLUSContextsHelper.setPageContext(); } // this seams to be a bug in seam (2.0.2.GA), not raised yet Manager.instance().unlockConversation(); return retVal; } /** * Delegator to BasicUtil. * @param e exception * @return string to be resolved from message bundle. */ public String getMessage(Throwable e) { String msg = BasicUtil.getMessage(e); return msg; } public String getNode() { return node; } public void setNode(String node) { this.node = node; } }
Pete, what do you think? Is that ready for a feature request?
-
3. Re: Handling Errors when usign JPDL Pageflow.
pmuir Oct 6, 2008 1:10 AM (in response to jnusaira)File the feature request, attach the code as a patch.
It's too late for me to think clearly right now ;-)
-
4. Re: Handling Errors when usign JPDL Pageflow.
ahus1 Oct 6, 2008 9:18 PM (in response to jnusaira) -
5. Re: Handling Errors when usign JPDL Pageflow.
ahus1 Oct 6, 2008 9:46 PM (in response to jnusaira)If you are interested in this feature, please vote for it in JIRA!
-
6. Re: Handling Errors when usign JPDL Pageflow.
pmuir Oct 6, 2008 9:54 PM (in response to jnusaira)Please use your real name in JIRA.
-
7. Re: Handling Errors when usign JPDL Pageflow.
hoann.hoan.nguyen.utiba.com Feb 23, 2009 3:15 AM (in response to jnusaira)I use the above work around in my project with SEAM 2.1.0.A1. It works fine.
However it stops working in SEAM 2.1.1.GA. I reckon that's because the recent change in org.jboss.seam.bpm.SeamExpressionEvaluator.In SEAM 2.1.0.A1
try { initMethodExpression(); } catch (javax.el.ELException e) { exceptions.add(e); } if (me != null) { try { return me.invoke(createELContext(resolver, mapper), new Object[0]); } catch (MethodNotFoundException e) { exceptions.add(e); } }
And in SEAM 2.1.1.GA
try { initMethodExpression(); if (me != null) { try { return me.invoke(createELContext(resolver, mapper), new Object[0]); } catch (MethodNotFoundException e) { exceptions.add(e); } } } catch (javax.el.ELException e) { exceptions.add(e); }
The method invocation has been brought into a try/catch for ELException. So a custom exception thrown by the method can never be seen outside the method.
That prevents my action handler knowing about the root cause of the exception.Can any one give me a hint to overcome this?
-
8. Re: Handling Errors when usign JPDL Pageflow.
hoann.hoan.nguyen.utiba.com Feb 23, 2009 3:18 AM (in response to jnusaira)Sorry for a typo.
So a custom exception thrown by the method can never be seen outside the methodshould be read
So a custom exception thrown by the method can never be seen outside Expression.evaluate() method -
9. Re: Handling Errors when usign JPDL Pageflow.
hoann.hoan.nguyen.utiba.com Feb 23, 2009 5:24 AM (in response to jnusaira)