I got some uncaught exception basically from an SQL operation via Primefaces AJAX call. Interestingly this uncaught exception APPEAR on FireBug's JavaScript secion as error:
<?xml version='1.0' encoding='UTF-8'?> <partial-response><error><error-name>class javax.faces.el.EvaluationException</error-name><error-message><![CDATA[Transaction rolled back]]></error-message></error></partial-response>
and on the server.log with all stacktrace and everything.
But I am unable to to bring it to the user attention without redirecting them to a separate error page (and lost all input data).
The proper way to handle this to create validator, which I will do, but there are always possibility of unaware database problem which will only appear doing the SQL operation. So I am only talk about no validator situation.
Let say I have this JSF snippet.
<h:form> <p:messages /> <..... primefaces (AJX) some button .... action="bean.save()" /> </h:form>
and the bean.save();
public void save() { try { em.merge(this.data); } catch(Exception e) { // never been in here EVEN if the data can't be merge for some constraint breaking reason. } }
If there is an database error, we will not see it until the transaction ends (AFTER save()) so I can't catch it. (This is confirmed with debug walk through and the fact that adding "em.flush()" here make the whole things works).
After looked left and right, I created a PhaseListener and I am able to get the exception. However, I am unable to show that exception on <p:messages />
public void afterPhase(final PhaseEvent event) { final Iterable exceptionEvents = event.getFacesContext().getExceptionHandler().getUnhandledExceptionQueuedEvents(); for (final ExceptionQueuedEvent exceptionEvent : exceptionEvents) { // This print out goes (found in server.log). System.out.println("Problem: " + exceptionEvent.getContext().getException()); // But this message does not. FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Problem", "Problem: " + exceptionEvent.getContext().getException())); } }
Any advice is very appreciated.