-
1. Re: Exception handling and redirects
zeeman Mar 21, 2012 3:11 PM (in response to blabno)I seam seam Solder and its exception handling mechanism. I catch all of exceptions I'm interested in like view expired, conversation, etc... for each one depending on my app needs I either redirect to a generic error page or I redirect to an error page that backed by a bean which has a custom error message set on it from the exception handler.
For protected URLs, I use ViewsConfig enum with Seam security and redirect to access denied view.
Of course the actual implementation could be tricky as you need to catch the right exceptions and put the right config. If you follow the examples from Seam and seam security and research this forum you'll have all the info you need.
-
2. Re: Exception handling and redirects
romanow Mar 22, 2012 12:58 AM (in response to zeeman)I have issue with my error page redirection, it works... sometimes.
My code:
public void handleSomeException(@Handles CaughtException<SomeException> event, HttpServletResponse response) {
...
event.handled();
...
response.sendRedirect("/myApp/errorPage");
produces exception:
java.lang.IllegalStateException: Attempted to inject an HttpServletResponse before it has been initialized.
It happen in some cases only, I guess it depends on the state of response.
Also I have trouble getting externalContext from FacesContext and have to hard-code myApp name.
Any Ideas?
-
3. Re: Exception handling and redirects
zeeman Mar 22, 2012 1:27 PM (in response to romanow)You want to use navigatino handler so your faces-config rules work and this works better as you don't need to worry about http response.
Here is what I use for view expired error:
public void onNonexistentConversation(@Handles final CaughtException<NonexistentConversationException> evt) { final NonexistentConversationException exception = evt.getException(); logger.error(exception); evt.handled(); // conversationContext.activate(null); // Workaround WELD-855 - Create a new transient conversation. FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "No conversation!", exception.getMessage()); final FacesContext facesContext = FacesContext.getCurrentInstance(); facesContext.addMessage(null, msg); facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, "", "error"); facesContext.renderResponse(); } -
4. Re: Exception handling and redirects
romanow Mar 23, 2012 10:39 PM (in response to zeeman)Zeeman,
Thank you for the suggestion.
I tried the code with the old catch-basic-servlet example. It doesn’t work because this line
final FacesContext facesContext = FacesContext.getCurrentInstance();
produces null.
Then I tried with my application producing JPA NonUniqueResultException and JSF ELException.
The code is called but redirection doesn’t happen.
I use Seam 3.1 final, AS 7.1.
I really thought that redirection to error page is a common issue and love the simplicity of Seam 2.
-
5. Re: Exception handling and redirects
zeeman Mar 24, 2012 8:36 PM (in response to romanow)If final FacesContext facesContext = FacesContext.getCurrentInstance(); is producing null that means you're not in a Faces request. Are you in a servlet or a filter when your exception occurs? If not, then you seem to have some config issues in your app.
I think catch-basic-servlet example is only a servlet so Faces context is not active. Try with booking example.
If you have your navigation in faces-config you send a redirect there like pages.xml in Seam 2:
For example, something I use:
<navigation-rule> <from-view-id>/home.xhtml</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <if>#{true}</if> <to-view-id>/home.xhtml</to-view-id> <redirect /> </navigation-case> </navigation-rule> If you want to redirect
-
6. Re: Exception handling and redirects
romanow Mar 26, 2012 9:24 PM (in response to zeeman)Thanks Zeeman,
I tried your code with the booking example, and the “sometimes” factor is still an issue.
I added 2 oversimplified pages to the booking example
wrongOnCall.xhtml:
template="/WEB-INF/layout/template.xhtml">
<ui:define name="content">
<h:form>
<h:commandButton value="call wrong" action="#{wrong.wrongCall}" />
</h:form>
</ui:define>
wrongOnLoad.xhtml
template="/WEB-INF/layout/template.xhtml">
<ui:define name="content">
<h:outputText value="#{wrong.user.email}" />
</ui:define>
</ui:composition>
my bean:
@Model
public class Wrong {
@PersistenceContext
private EntityManager em;
public User getUser() {
TypedQuery<User> query = em.createQuery("FROM User ", User.class);
User user = query.getSingleResult();
return user;
}
public void wrongCall(){
TypedQuery<User> query = em.createQuery("FROM User ", User.class);
User user = query.getSingleResult();
}
}
and error handler:
public void onNonUniqueResultException(@Handles final CaughtException<NonUniqueResultException> evt) {
final NonUniqueResultException exception = evt.getException();
evt.handled();
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Some text", exception.getMessage());
final FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage(null, msg);
facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, "", "error");
facesContext.renderResponse();
}
Both pages cost NonUniqueResultException.
In both cases the onNonUniqueResultException IS executed.
Error page happen only for wrongOnCall.xhtml. (The URL stays the same, but this is not showstopper)
Thus, when exception happen during page load redirection doesn’t kick in.
At the same time part of the page without exception is rendered just fine. In my case I got page with menu bar only which is not very pretty.
-
7. Re: Exception handling and redirects
zeeman Mar 27, 2012 3:12 AM (in response to romanow)I think you have a specific use case that you need to handle. If you have logic that executes on page load and throws an exception, you need to handle that correctly.
You need to redirect if you have not started writing back to the client, if you have, how is the browser going to redirect? It's not magic.
Two suggestions; either move your logic from being excuted on page load, or set a flag in flash scope if an error occurs once a page loads, check for that flag, then redirect if it's true.
To fix the issue with the url staying the same, add </redirect> to your error nav case.
I think my answers get what you want here.