dev@javaserverfaces.java.net

Re: What to do when an exception is thrown during ajax rendering?

From: Edward Burns <edward.burns_at_oracle.com>
Date: Fri, 7 Feb 2014 13:26:44 -0800

>>>>> On Fri, 7 Feb 2014 10:05:08 -0500, Kito Mann <kito.mann_at_virtua.com> said:

KM> +1
KM> While we're talking about the ErrorHandler, it would be nice to get an
KM> error page in this scenario instead of requiring the developer to handle
KM> this via JS. I have to do this in every project I'm on, and OmniFaces has
KM> this feature as well. I should have brought this up during the JSF 2.2
KM> work...

But because it's Ajax, I think we really want to stick with our
precedent and require the JS. This proposal just gives you the ability
to have your error handler called if there's an error during rendering.

>>>>> On Fri, 07 Feb 2014 13:22:24 -0500, Andy Schwartz <andy.schwartz_at_oracle.com> said:

AS> Hi Ed -
AS> On 2/6/14 4:14 PM, Edward Burns wrote:

EB> If #{bean.throwExceptionOnAjax} throws an exception? What should happen
EB> to the handleError()? It should get invoked, right?

AS> Sure.

EB> Well, it doesn't. Instead, we get an exception about nested CDATA.
EB>
EB> That's the first problem.
EB>
EB> Once we fix the nested CDATA problem, we now see that the error handler
EB> is not invoked because the status is not set to 500.
EB>
EB> Here are my questions to the community.
EB>
EB> Should an exception occurring during render cause an HTTP 500 error to
EB> be set as the status of the Ajax response?
EB>

AS> Would that require buffering up the entire response just in case we end
AS> up needing to call sendError(500)? If so, I would rather that we not do
AS> this.

No, I specifically want to avoid buffering entirely. In fact, I started
with a buffering solution, but it started to get too complicated and I
decided to pursue this other approach.

EB> Should we allow the ajax error handler to take effect when the rendering
EB> contains broken CDATA rendered response text?
EB>

AS> Seems reasonable.

EB> I have a patch that makes it so both of things are true.
EB>

AS> How do you set the response status code after rendering has started?

I had been setting it in the AjaxExceptionHandler, which gets control
right after the exception is thrown. However, the existing
implementation sends a 200 back even in an error case, but the jsf.js
looks for the firstChild of the <partial-response> to be <error> to
differentiate the error case from the success case.

Thus, when I changed it to send back a 500, some other automated tests
started failing.

The solution I have now keeps the 200, but keeps the partial response as
before.

EB> Here is the partial Ajax response with the proposed fix in place:
EB>
EB> <?xml version='1.0' encoding='UTF-8'?>
EB> <partial-response id="j_id1">
EB> <changes>
EB> <update id="willThrowException">
EB> <![CDATA[
EB> <partial-response id="j_id1">
EB>

AS> This would be something like "<span id="j_id1">" as opposed to a nested
AS> <partial-response> element, right?

EB> ]]>
EB> </update>
EB> </changes>
EB> <error>
EB> <error-name>class java.lang.RuntimeException</error-name>
EB> <error-message>
EB> <![CDATA[
EB> Intentionally throwing exception on ajax request
EB> ]]>
EB> </error-message>
EB> </error>
EB> </partial-response>
EB>
EB> Is this ok?
EB>

AS> Sounds fine. Does the xsd for partial response payloads allow this?

Sadly, it does not, it needs a small tweak, which I covered in
<https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1262>.
However, because I don't think browsers are using that XSD, I think we
are ok in the implementation as long as the XML is well formed.

AS> Would we attempt to apply the <changes> if an <error> is present later
AS> on in the payload?

No. I propose the presence of an <error> makes it so the error handler
is invoked and the changes are not applied.

AS> If the <changes> content contains invalid content (cannot be parsed), do
AS> we call the error handler?

Yes, this already happens.

AS> If yes, does the error handler get called
AS> twice (once for the invalid <changes> content and again for the <error>)?

No, it does not.

I've attached a changebundle to
<https://java.net/jira/browse/JAVASERVERFACES-3171>. I'd appreciate a
review.

Ed


-- 
| edward.burns_at_oracle.com | office: +1 407 458 0017
| 11 Work Days Til DevNexus 2014
| 28 Work Days Til JavaLand 2014