0

I'm using a <h:selectOneMenu> with an valueChangeListener attribute attached to it. The listener invokes some business code (eg. DB query) to load additional data based on the new selected value. I noticed that when an (unexpected) exception happens in that code, a AbortProcessingException wraps the original exception, which is followed by a log but without notifying the user that something went wrong.

Is there a way to notify the user that something unexpected went fatally wrong when invoking a listener ?

I know from Differences between action and actionListener that an action would be more appropriate for such an expression, however I cannot set an action in <h:selectOneMenu>, but only a listener. How shall I change my page so that a "real business action" (one that is allowed to fail) gets invoked when the selected item changes ?

Community
  • 1
  • 1
Gaetan
  • 2,802
  • 2
  • 21
  • 26

1 Answers1

0

JSF has a concept of FacesMessages. These are rendered with the help of the <h:messages /> tag. What is often done, is to catch any Exceptions and add a javax.faces.application.FacesMessage to the FacesContext, giving the user informations he needs (see also "catch exception in managed bean and show message on screen in jsf2").

FacesContext.getCurrentInstance().addMessage(
    null, 
    new FacesMessage(Severity.INFO, <see details for possible fills>)
);

There are also the way to introduce an own ExceptionHandlerFactory - like mentioned in the article "Global handling of all unchecked / unexpected exceptions in JSF 2"- have you checked this possibility? (see also this answer/comment to BalcusCs article )

As possibility two, you can e.g. use an ajax-request after the selectOneMenu got changed and trigger another Listener with that (it is executed later then the ValueChangedListener and gives the AjaxBehaviorEvent as parameter, what I find to be more helpful on BL - side). Here is some meta-code ...

<h:selectOneMenu ...>
  <f:selectItems ... />
  <f:ajax render="..." execute="..." listener="..." />
</h:selectOneMenu>

Hope it helps...

Community
  • 1
  • 1
L-Ray
  • 1,637
  • 1
  • 16
  • 29
  • I do not want to wrap each listener within `try {...} catch (Exception) {addMessage("error");}`. I would expect the same behaviour as a plain action : any fatal/unexpected exception is only caught by the web-server and an error page is displayed. – Gaetan Jan 15 '14 at 14:50
  • Further, solution 2 still invokes a listener, and JSF will swallow any exception that is raised by the listener. – Gaetan Jan 15 '14 at 14:53
  • Always happy to help you achieving your goals. That's right, a listener usually swallows the exceptions, so solution 1 helps you catch it and send an individual message to the user via FacesMessages. If you want a "one-size-fits-all"-solution, investigate the `ExceptionHandlerFactory` solution. You are also right, that the f:ajax-listener is "just another listener", but because it is executed in an other part of the lifecycle, it might give you additional possibilities, e.g. forwarding/redirecting. It's your project, your decisions. – L-Ray Jan 15 '14 at 15:19