fixes bug where displaying an error page for missing data source would also require that data source (error pages don't try to get database connections now)

Sat, 16 May 2020 15:45:06 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 16 May 2020 15:45:06 +0200
changeset 53
6a8498291606
parent 52
67a02e79b7a1
child 54
77e01cda5a40

fixes bug where displaying an error page for missing data source would also require that data source (error pages don't try to get database connections now)

also improves error pages in general

src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/modules/ErrorModule.java file | annotate | diff | comparison | revisions
src/main/resources/localization/error.properties file | annotate | diff | comparison | revisions
src/main/resources/localization/error_de.properties file | annotate | diff | comparison | revisions
src/main/webapp/WEB-INF/dynamic_fragments/error.jsp file | annotate | diff | comparison | revisions
src/main/webapp/WEB-INF/web.xml file | annotate | diff | comparison | revisions
src/main/webapp/error.css file | annotate | diff | comparison | revisions
--- a/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java	Sat May 16 15:11:07 2020 +0200
+++ b/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java	Sat May 16 15:45:06 2020 +0200
@@ -324,13 +324,28 @@
         }
 
         // set some internal request attributes
+        final String fullPath = Functions.fullPath(req);
         req.setAttribute(Constants.REQ_ATTR_BASE_HREF, Functions.baseHref(req));
-        req.setAttribute(Constants.REQ_ATTR_PATH, Functions.fullPath(req));
+        req.setAttribute(Constants.REQ_ATTR_PATH, fullPath);
         Optional.ofNullable(moduleInfo).ifPresent((proxy) -> req.setAttribute(Constants.REQ_ATTR_MODULE_INFO, proxy));
 
+        // if this is an error path, bypass the normal flow
+        if (fullPath.startsWith("/error/")) {
+            final var mapping = findMapping(method, req);
+            if (mapping.isPresent()) {
+                forwardAsSpecified(invokeMapping(mapping.get(), req, resp, null), req, resp);
+            }
+            return;
+        }
+
         // obtain a connection and create the data access objects
         final var db = (DatabaseFacade) req.getServletContext().getAttribute(DatabaseFacade.SC_ATTR_NAME);
-        try (final var connection = db.getDataSource().getConnection()) {
+        final var ds = db.getDataSource();
+        if (ds == null) {
+            resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "JNDI DataSource lookup failed. See log for details.");
+            return;
+        }
+        try (final var connection = ds.getConnection()) {
             final var dao = createDataAccessObjects(connection);
             try {
                 connection.setAutoCommit(false);
--- a/src/main/java/de/uapcore/lightpit/modules/ErrorModule.java	Sat May 16 15:11:07 2020 +0200
+++ b/src/main/java/de/uapcore/lightpit/modules/ErrorModule.java	Sat May 16 15:45:06 2020 +0200
@@ -32,6 +32,7 @@
 
 import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.Optional;
 
 /**
@@ -49,13 +50,10 @@
 )
 public final class ErrorModule extends AbstractLightPITServlet {
 
-    public static final String REQ_ATTR_ERROR_CODE = "errorCode";
     public static final String REQ_ATTR_RETURN_LINK = "returnLink";
 
-    private ResponseType handle(HttpServletRequest req, int sc) {
-
-        req.setAttribute(REQ_ATTR_ERROR_CODE, sc);
-
+    @RequestMapping(requestPath = "generic", method = HttpMethod.GET)
+    public ResponseType onError(HttpServletRequest req, HttpServletResponse resp) {
         Optional.ofNullable(req.getHeader("Referer")).ifPresent(
                 referer -> req.setAttribute(REQ_ATTR_RETURN_LINK, referer)
         );
@@ -65,19 +63,4 @@
 
         return ResponseType.HTML;
     }
-
-    @RequestMapping(requestPath = "404.html", method = HttpMethod.GET)
-    public ResponseType handle404(HttpServletRequest req) {
-        return handle(req, 404);
-    }
-
-    @RequestMapping(requestPath = "403.html", method = HttpMethod.GET)
-    public ResponseType handle403(HttpServletRequest req) {
-        return handle(req, 403);
-    }
-
-    @RequestMapping(requestPath = "500.html", method = HttpMethod.GET)
-    public ResponseType handle500(HttpServletRequest req) {
-        return handle(req, 500);
-    }
 }
--- a/src/main/resources/localization/error.properties	Sat May 16 15:11:07 2020 +0200
+++ b/src/main/resources/localization/error.properties	Sat May 16 15:45:06 2020 +0200
@@ -26,10 +26,11 @@
 h1 = The requested page cannot be displayed.
 errorCode = Code
 
-errorMessage = Message
-errorMessage.404 = Page not found
-errorMessage.403 = Access denied
-errorMessage.500 = Internal error
+errorMessage = Server Message
+code.404 = Page not found
+code.403 = Access denied
+code.500 = Internal error
+code.503 = Service unavailable
 
 errorTimestamp = Timestamp
 errorExceptionText = Internal Exception
--- a/src/main/resources/localization/error_de.properties	Sat May 16 15:11:07 2020 +0200
+++ b/src/main/resources/localization/error_de.properties	Sat May 16 15:45:06 2020 +0200
@@ -26,10 +26,11 @@
 h1 = Die angeforderte Seite kann nicht angezeigt werden.
 errorCode = Fehlercode
 
-errorMessage = Nachricht
-errorMessage.404 = Seite nicht gefunden
-errorMessage.403 = Zugriff verboten
-errorMessage.500 = Interner Fehler
+errorMessage = Server Nachricht
+code.404 = Seite nicht gefunden
+code.403 = Zugriff verboten
+code.500 = Interner Fehler
+code.503 = Dienst steht derzeit nicht zur Verfügung
 
 errorTimestamp = Zeitstempel
 errorExceptionText = Interne Ausnahme
--- a/src/main/webapp/WEB-INF/dynamic_fragments/error.jsp	Sat May 16 15:11:07 2020 +0200
+++ b/src/main/webapp/WEB-INF/dynamic_fragments/error.jsp	Sat May 16 15:45:06 2020 +0200
@@ -32,7 +32,7 @@
 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
 
 <c:set scope="page" var="baseHref" value="${requestScope[Constants.REQ_ATTR_BASE_HREF]}" />
-<c:set scope="page" var="errorCode" value="${requestScope[ErrorModule.REQ_ATTR_ERROR_CODE]}"/>
+<c:set scope="page" var="errorCode" value="${requestScope['javax.servlet.error.status_code']}"/>
 <c:set scope="page" var="returnLink" value="${requestScope[ErrorModule.REQ_ATTR_RETURN_LINK]}"/>
 
 <div id="error-page">
@@ -40,11 +40,11 @@
     <table>
         <tr>
             <th><fmt:message key="errorCode"/>:</th>
-            <td>${errorCode}</td>
+            <td>${errorCode} - <fmt:message key="code.${errorCode}" /></td>
         </tr>
         <tr>
             <th><fmt:message key="errorMessage" />:</th>
-            <td><fmt:message key="errorMessage.${errorCode}" /></td>
+            <td><c:out value="${requestScope['javax.servlet.error.message']}"/></td>
         </tr>
         <tr>
             <th><fmt:message key="errorTimestamp" />:</th>
--- a/src/main/webapp/WEB-INF/web.xml	Sat May 16 15:11:07 2020 +0200
+++ b/src/main/webapp/WEB-INF/web.xml	Sat May 16 15:45:06 2020 +0200
@@ -17,15 +17,6 @@
         <lookup-name>java:/jdbc/lightpit/app</lookup-name>
     </resource-ref>
     <error-page>
-        <error-code>404</error-code>
-        <location>/error/404.html</location>
-    </error-page>
-    <error-page>
-        <error-code>403</error-code>
-        <location>/error/403.html</location>
-    </error-page>
-    <error-page>
-        <error-code>500</error-code>
-        <location>/error/500.html</location>
+        <location>/error/generic</location>
     </error-page>
 </web-app>
--- a/src/main/webapp/error.css	Sat May 16 15:11:07 2020 +0200
+++ b/src/main/webapp/error.css	Sat May 16 15:45:06 2020 +0200
@@ -48,6 +48,7 @@
 
 #error-page table th {
     text-align: right;
+    white-space: nowrap;
 }
 
 #error-page table td {

mercurial