Hi Carlin,

Sorry for the delay on this. I think that your first proposed solution (fixing PageFlowRequestProcessor.processException()) is something we should do anyway -- I must have missed that case early on.

I do also think it would be fine to catch the exceptions in beginContext/endContext up-front, if it doesn't twist the code there into knots.

Hope this helps.
Rich

Carlin Rogers wrote:
Beehive Devs,

I've been looking at exception handing with respect to control container
management and wanted to get some feedback or ideas from the dev group.
Sorry for the long note. Hopefully the details do not cause too much
confusion.

In NetUI today, when an action is executed, the FlowController.execute()
method goes through the following general steps.

- get the page flow control container and call beginContext() on the
ControlContainerContext.
- execute the beginAction, Action, afterAction code (in
FlowController.internalExecute ())
  -- call the beforeAction() callback
  -- execute the actual action method
  -- call the beforeAction() callback
- perform the endContext() on the page flow ControlContainerContext.

Note, in the FlowController.internalExecute() method where we actually
execute the action method, we already have exception handling in place. If
an exception is thrown at this stage in the NetUI framework, we will catch
it and call the FlowController method, handleException(), to invoke user
code if appropriate and return a destination URI. We also set the exception
being handled in the PageFlowRequestWrapper.

However, if an exception is thrown during the beginContext()/endContext() in
the page flow Control container management, we do not catch the exception
and run it through handleException(). Instead, the exception is caught in
the processActionPerform() method of the Struts framework, then passed to
the RequestProcessor method processException(). If there's no matching
exception config, processException() will throw a new ServletException with
the "root cause" exception.

Unfortunately, when there is a user defined exception handler associated to
the exception, processException()  does not properly handle an exception
config for the NetUI page flow exception handler. In this case, a
ClassNotFoundException occurs in the Struts code when it tries to create an
ExceptionHandler from the exception config. Struts expects the handler
attribute of the exception element in the struts config to be a fully
qualified Java class name.  In NetUI we generate just the method name of the
page flow Controller exception handler. This causes the CNFE. Then, a
ServletException also gets thrown but doesn't wrap the root cause.

The ServletException is eventually caught in the PageFlowRequestProcessor
(in processInternal()). We then try to run it through the NetUI framework
support in FlowController.handleException(). The exception could still
result in an HTTP status 500 page if an exception has already been handled
during the actual action method execution, it's not a framework exception,
or one that a developer has written a handler.

In general, I think the above works fine as designed. The only case that
causes an issue is when a user has defined a NetUI exception handler for the
exception thrown during the control container context management. This is
the scenario that causes the CNFE described above. I think this one case may
cause confusion.

One possible solution is to leave the exception handling as is but just
change our PageFlowRequestProcessor.processException() override to check if
the ExceptionConfig is an instance of PageFlowExceptionConfig. Then we could
try to handle the exception with FlowController.handleException(), rather
than falling into the Struts super class implementation,
RequestProcessor.processException(), to avoid the CNFE.

Other thoughts? Should we explicitly try to catch exceptions in
FlowController.execute() when we do the beginContext/endContext rather than
let them bubble up? If so, should we just log them, or try to run them
through the FlowController.handleException().

Thanks for the help. Kind regards,
Carlin


Reply via email to