2 Replies Latest reply on Mar 10, 2008 10:19 AM by amolch

    Exception handling in JSF

    amolch

      Hello All,
      I am facing a peculiar problem, while i am trying to handle exceptions in my JSF application. I am using Ajax4JSF commandButton to call a saveAction method in my backing bean. This method in turn calls a service which throws a BusinessException depending on some business logic. Now i want to show some meaningful message to the user as per the error code of the Exception.

      To show that message, i have tried 2 things:
      1. i tried catching the exception in my saveAction and added the necessary faces message to FacesContext object. But it does not work. Later i read the reason behind this too, that in the invoke application phase a new context will be created and the messages will not be available to it.

      2. I then added the throws clause to my saveAction method, so that my default exception handler will handle it.

      saveAction method signature :

      public String saveAction () throws BusinessException {
       //some code here for save
       return null;
      }
      


      This is my code for the ErrorHandler.jsp:

      <body>
       <h1 style="color: red">Error</h1><br/><%
       // print stack trace.
       ExceptionHandler exceptionHandler = new ExceptionHandler();
      
       // unwrap ServletExceptions.
       while (exception instanceof ServletException || exception instanceof FacesException ||
       exception instanceof ApplicationException) {
       if(exception instanceof ServletException) {
       exception = ((ServletException) exception).getRootCause();
       } else if(exception instanceof FacesException) {
       exception = ((FacesException) exception).getCause();
       } else if(exception instanceof ApplicationException) {
       exception = ((ApplicationException) exception).getCause();
       }
       }
       %><font color="red"><%=exceptionHandler.handleException(exception)%></font><br/></body>
      


      and this is my code for the handleException method defined in the ExceptionHandler.java:
      public static String getMessage(final String msgKey, final Object args[]) {
       String message = messages.getProperty(msgKey);
       if(args != null) {
       final String replaceArgs[] = (String[]) args;
       for(int i = 0; i < replaceArgs.length; i++)
       message = message.replaceFirst("{" + i + "}", replaceArgs);
      
       }
       return message;
       }
      
       public String handleException(final Throwable exception) {
       logger.debug("handleException called..");
      
       String errorMessage = "Unknown error occured.";
       String stackTrace = "Stacktrace can not be found. Please check the logs for more details.";
       String errorString = null;
      
       final StringWriter stringWriter = new StringWriter();
       if(exception != null) {
       exception.printStackTrace (new PrintWriter (stringWriter));
       stackTrace = stringWriter.toString();
      
       errorMessage = getMessage(exception.getMessage(), null);
       }
      
       errorString = "<b>" + errorMessage + "</b> <br> </br> <br> <input id=\"show\" type=\"button\" value=\"Show Details >>\" onClick=\"toggle();\" /> <div id="\"errorStackTrace\"" style="\"display:none;\""> <pre>" + stackTrace + "</pre> </div>";
      
       return errorString;
       }
      


      I have the following code in my web.xml
       <error-page>
       <exception-type>java.lang.Exception</exception-type>
       <location>/faces/ErrorHandler.jsp</location>
       </error-page>
       <error-page>
       <error-code>403</error-code>
       <location>/ErrorPageAuthorization.html</location>
       </error-page>
       <error-page>
       <error-code>500</error-code>
       <location>/faces/ErrorHandler.jsp</location>
       </error-page>
      


      With the help of this code, i am simply trying to navigate to the error page if an exception occurs and display the appropriate error message with the stacktrace.

      Now the ErrorHandler.jsp page correctly gets called, which in turn calls the handleException method which returns the formatted error string. (I checked this by adding log statements everywhere). But the system does not actually navigates to the ErrorHandler.jsp page and shows an alert with the following message : "Request error, status : 500 Internal Server Error message : "

      Now the strange thing is, if i call the saveAction method normally (i.e. without using Ajax4JSF) then the things work as expected and the error message is shown properly.

      But if i call the saveAction method using a4j:commandButton click, i get the above error.

      Can anyone help me on this?