-
1. Re: Exception Filter and Page Parameters
mtorres Apr 24, 2009 7:39 PM (in response to mtorres)The main reason we have the above use case is we're trying to have a centralized exception handling where our application level Exceptions will be caught, logged, and have the message recorded into JSF. The request is then redirected to the same page(we're not hardcoding errorTest.xhtml) for redisplay. Most of our pages works well with the exception handling pattern described above.
Some pages though, maintains their state in page parameters, instead of session or conversation and thus we need the page parameters during redirect. Rendering within the same request cycle, would have conceptually worked for us but I did not know of a way to do that with the ExceptionsFilter.
As a workaround for this problem, we tried to do the exception handling via a Java Interceptor approach. JSF facing components will mostly be annotated with ExceptionsAware, that triggers the ExceptionsAwareInterceptor. This interceptor encloses the invocation inside a try, catch block and delegates exception handling to the ExceptionsExt component, which is basically the built in Exceptions component that we overrode to remove some of the events publishing. The invocation is only wrapped inside a try/catch during the outermost interception within a call stack, thus the marker on the event context. This approach allowed us to not redirect during exceptions. In addition, I think, we can reuse the navigation rules in pages.xml to redirect/render to other views during exceptions, although we dont have such requirement yet so I still need to test it.
I'd appreciate your insight into this, do you think this is a workeable solution?
@Interceptor(stateless = true, around = TransactionInterceptor.class) public class ExceptionsAwareInterceptor extends AbstractInterceptor{ private static final String EVENT_MARKER_NAME = ExceptionsAwareInterceptor.class.getName() + "_EventMarker"; public Object aroundInvoke(InvocationContext ic) throws Exception { Method method = ic.getMethod(); ExceptionsAware tag=null; if ( method.isAnnotationPresent(ExceptionsAware.class) ) { tag = method.getAnnotation(ExceptionsAware.class); }else if (ic.getTarget()!=null && ic.getTarget().getClass().isAnnotationPresent(ExceptionsAware.class)){ tag = ic.getTarget().getClass().getAnnotation(ExceptionsAware.class); } if (tag.enabled()){ Boolean marker = (Boolean)Contexts.getEventContext().get(EVENT_MARKER_NAME); if (ObjectUtilsExt.eval(marker)){ //marked, let it pass through return ic.proceed(); }else{ //not marked, first for the call stack, do handling here. try{ //mark Contexts.getEventContext().set(EVENT_MARKER_NAME,Boolean.TRUE); return ic.proceed(); }catch (Exception e) { ExceptionsExt.instance().handle(e); return null; }finally{ //remove the marker here. Contexts.getEventContext().remove(EVENT_MARKER_NAME); } } }else{ return ic.proceed(); } } public boolean isInterceptorEnabled() { return getComponent().beanClassHasAnnotation(ExceptionsAware.class); } }