2

Following this solution I made an error page like this:

In faces-config.xml

<error-page>
    <error-code>500</error-code>
    <location>/errore500.xhtml</location>
</error-page>

....

<managed-bean>
    <managed-bean-name>errore</managed-bean-name>
    <managed-bean-class>it.jlp.prometheus.modello.Errore</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

... the page errore500.xhtml ...

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <meta name="author" content="JLP" />
    <link rel="stylesheet" href="css/stile.css" type="text/css" />
    <link rel="icon" href="icons/favicon.png" type="image/png" />
    <title>Prometheus - Error 500</title>
</head>

<body>
    <h:form>

....

 <br/><h:inputTextarea style="width: 100%;" rows="20" readonly="true"
                                          value="#{errore.stackTrace}" />

 ....

...and the class Errore

public class Errore implements Serializable {

private Log logger = LogFactory.getLog(Errore.class);

public String getStackTrace() {
    FacesContext context = FacesContext.getCurrentInstance();
    Map requestMap = context.getExternalContext().getRequestMap();
    Throwable ex = (Throwable) requestMap.get("javax.servlet.error.exception");
    StringWriter writer = new StringWriter();
    PrintWriter pw = new PrintWriter(writer);
    fillStackTrace(ex, pw);
    logger.info("****** getStackTrace executed ");
    return writer.toString();
}

private void fillStackTrace(Throwable ex, PrintWriter pw) {
    if (null == ex) {
        return;
    }
    ex.printStackTrace(pw);
    if (ex instanceof ServletException) {
        Throwable cause = ((ServletException) ex).getRootCause();
        if (null != cause) {
            pw.println("Root Cause:");
            fillStackTrace(cause, pw);
        }
        } else {
        Throwable cause = ex.getCause();

        if (null != cause) {
            pw.println("Cause:");
            fillStackTrace(cause, pw);
        }
    }
}

With this code, when I cause intentionally an ecception (a ClassCastException) in another part of application, it redirect me to this page but, by putting a debug print log in the backing bean class I saw that this is never instantiated, thus the text area doesn't get populated. Why the backing bean is never instantiated?

Community
  • 1
  • 1
JLPicard
  • 21
  • 3

1 Answers1

1

The location

<location>/errore500.xhtml</location>

must match the URL pattern of the FacesServlet.

So if it is for example mapped on

<url-pattern>*.jsf</url-pattern>

then you need to set the location to

<location>/errore500.jsf</location>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I have in web.xml this piece of configuration: ` javax.faces.DEFAULT_SUFFIX .xhtml ... Faces Servlet javax.faces.webapp.FacesServlet 1 Faces Servlet *.faces ` Should I change location with errore500.faces? – JLPicard May 26 '11 at 08:23
  • 1
    Yes, the URL pattern of the `FacesServlet`. – BalusC May 26 '11 at 10:51
  • Sorry, but didn't work. Could be something else? Maybe faces configuration stuff? – JLPicard May 27 '11 at 11:37