package com.elibom.jogger; import java.io.PrintWriter; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import com.elibom.jogger.exception.WebApplicationException; import com.elibom.jogger.http.Http.Headers; import com.elibom.jogger.http.Request; import com.elibom.jogger.http.Response; import freemarker.template.Configuration; /** * This is the default exception handler used internally by {@link Jogger}, triggered when no other middleware handles an * exception. * * @author German Escobar */ public class DefaultExceptionHandler implements ExceptionHandler { private Configuration freemarker; public DefaultExceptionHandler() { this.freemarker = new Configuration(); this.freemarker.setClassForTemplateLoading(Jogger.class, "/templates/"); } public void handle(Exception e, Request request, Response response) { if (WebApplicationException.class.isInstance(e)) { handleWebApplicationException((WebApplicationException) e, request, response); } else { handleException(e, request, response); } } private void handleWebApplicationException(WebApplicationException wae, Request request, Response response) { response.status(wae.getStatus()); Map<String,Object> root = new HashMap<String,Object>(); root.put("title", wae.getStatus() + " " + wae.getName()); root.put("message", wae.getMessage()); if (wae.getCause() != null) { root.put("stackTrace", getStackTrace(wae.getCause())); } if (wae.getStatus() == Response.INTERNAL_ERROR) { render(request, response, root, "500.ftl"); } else { render(request, response, root, "4xx.ftl"); } } private void handleException(Exception e, Request request, Response response) { response.status(Response.INTERNAL_ERROR); Map<String,Object> root = new HashMap<String,Object>(); root.put("title", Response.INTERNAL_ERROR + " " + "Internal Server Error"); root.put("message", e.getMessage()); root.put("stackTrace", getStackTrace(e)); render(request, response, root, "500.ftl"); } private void render(Request request, Response response, Map<String,Object> root, String template) { if (isHtmlRequest(request)) { StringWriter writer = new StringWriter(); try { freemarker.getTemplate(template).process(root, writer); response.contentType("text/html; charset=UTF-8"); response.write(writer.toString()); } catch (Exception e) { response.write("<h1>" + root.get("title") + "</h1><p>" + root.get("message") + "</p>"); } } } private boolean isHtmlRequest(Request request) { String accepts = request.getHeader(Headers.ACCEPT); if (accepts != null && accepts.contains("html")) { return true; } return false; } private String getStackTrace(Throwable exception) { StringWriter errors = new StringWriter(); exception.printStackTrace(new PrintWriter(errors)); return errors.toString(); } }