4
\$\begingroup\$

I hate using unnecessary catch blocks and I like to see my code look beautiful. In most of the cases in my project, which is a web application, I can't declare many exceptions as checked exceptions as there is little that my client (browser) can do to recover from the exception. However, only if there is a way that the client of my code (mostly fellow programmer) can gracefully handle the exceptions, I am declaring such exceptions as checked exceptions (so that there are few throws clauses as possible).

I am trying to hide the implementation detail specific checked exceptions of my DAO classes from being known to the Service layer (by wrapping the exception in a layer specific checked exception).

I have the following approach for logging and displaying error messages to the user in the JSPs. I am logging exceptions in a centralized place. A Servlet Filter:

public class WebAppUtils {

    private static final Logger logger = LoggerFactory.getLogger(WebAppUtils.class);

    //Called from the Filter's doFilter() method, which is mapped to /*
    public static void log(ServletRequest request, ServletResponse response, FilterChain chain) {
        try {
            chain.doFilter(request, response);
        } catch (Throwable exception) {
            String rootCauseMessage = ExceptionUtils.getRootCauseMessage(exception);
            request.setAttribute("rootCauseMessage", rootCauseMessage);
            if (exception instanceof RuntimeException) {
                logger.error("A Runtime Exception has occurred. The cause is " + rootCauseMessage, exception);
                throw new RuntimeException();
            }
            if (exception instanceof Exception) {
                logger.error("An Exception has occurred. The cause is " + rootCauseMessage, exception);
            } else {
                logger.error("An Error has occurred. The cause is " + rootCauseMessage, exception);
            }
            throw new RuntimeException();
        }
    }


    //Called when context is being destoyed
    public static void cleanUp() {
        deRegister();

        if (logger.isInfoEnabled()) {
            logger.info("Jdbc drivers have been " +
                    "de-registered to prevent memory leak. Shutting down loggers.");
        }
        LogManager.shutdown();
    }

    private static void deRegister() {
        Enumeration<Driver> drivers = DriverManager.getDrivers();
        while (drivers.hasMoreElements()) {
            Driver driver = drivers.nextElement();
            try {
                DriverManager.deregisterDriver(driver);
                logger.info(String.format("De-registering jdbc driver: %s", driver));
            } catch (SQLException e) {
                logger.info(String.format("Error de-registering driver %s", driver), e);
            }
        }
    }
}

My web.xml:

<filter>
    <filter-name>logger</filter-name>
    <filter-class>com.mycompany.ExceptionLogger</filter-class>
</filter>

<filter-mapping>
    <filter-name>logger</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/WEB-INF/error.jsp</location>
</error-page>

Error Page:

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


    <div>
        //This shows the caused exception name with the optional message. 
        //I am not too happy with it as the user may not be interested in my custom exception name. 
        //How can I improve this?

            Oops! Something went wrong. The cause is 
            <span>
                <c:if test="${!empty requestScope.rootCauseMessage}">
                    <c:out value="${requestScope.rootCauseMessage}"/>
                </c:if>
            </span>

    </div>

How can I improve the shown approach for logging and is there any better way to report error conditions(in a more meaningful way than the one showed)to the user in JSPs?

\$\endgroup\$
0

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.