Do not drop the exception in the error handler When an HTML rendering fails, the handler drops the exception without saying anything. Add the rendering exception as a suppressed exception and rethrow the original exception. This helps debugging an issue that the handler is trying to change the status code for the committed response. Change-Id: I9e2e73222cd71df6bd6ebef7b12d385abb6531af Signed-off-by: Masaya Suzuki <[email protected]>
diff --git a/java/com/google/gitiles/DefaultErrorHandlingFilter.java b/java/com/google/gitiles/DefaultErrorHandlingFilter.java index f558c0d..459347c 100644 --- a/java/com/google/gitiles/DefaultErrorHandlingFilter.java +++ b/java/com/google/gitiles/DefaultErrorHandlingFilter.java
@@ -45,32 +45,68 @@ @Override public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException { - int status = -1; - String message = null; try { chain.doFilter(req, res); } catch (GitilesRequestFailureException e) { - res.setHeader(GITILES_ERROR, e.getReason().toString()); - status = e.getReason().getHttpStatusCode(); - message = e.getPublicErrorMessage(); + try { + res.setHeader(GITILES_ERROR, e.getReason().toString()); + renderHtml(req, res, e.getReason().getHttpStatusCode(), e.getPublicErrorMessage()); + } catch (IOException e2) { + e.addSuppressed(e2); + throw e; + } } catch (RepositoryNotFoundException e) { - status = FailureReason.REPOSITORY_NOT_FOUND.getHttpStatusCode(); - message = FailureReason.REPOSITORY_NOT_FOUND.getMessage(); + try { + res.setHeader(GITILES_ERROR, FailureReason.REPOSITORY_NOT_FOUND.toString()); + renderHtml( + req, + res, + FailureReason.REPOSITORY_NOT_FOUND.getHttpStatusCode(), + FailureReason.REPOSITORY_NOT_FOUND.getMessage()); + } catch (IOException e2) { + e.addSuppressed(e2); + throw e; + } } catch (AmbiguousObjectException e) { - status = FailureReason.AMBIGUOUS_OBJECT.getHttpStatusCode(); - message = FailureReason.AMBIGUOUS_OBJECT.getMessage(); + try { + res.setHeader(GITILES_ERROR, FailureReason.AMBIGUOUS_OBJECT.toString()); + renderHtml( + req, + res, + FailureReason.AMBIGUOUS_OBJECT.getHttpStatusCode(), + FailureReason.AMBIGUOUS_OBJECT.getMessage()); + } catch (IOException e2) { + e.addSuppressed(e2); + throw e; + } } catch (ServiceMayNotContinueException e) { - status = e.getStatusCode(); - message = e.getMessage(); - } catch (IOException | ServletException err) { - log.warn("Internal server error", err); - status = FailureReason.INTERNAL_SERVER_ERROR.getHttpStatusCode(); - message = FailureReason.INTERNAL_SERVER_ERROR.getMessage(); + try { + renderHtml(req, res, e.getStatusCode(), e.getMessage()); + } catch (IOException e2) { + e.addSuppressed(e2); + throw e; + } + } catch (IOException | ServletException e) { + try { + log.warn("Internal server error", e); + res.setHeader(GITILES_ERROR, FailureReason.INTERNAL_SERVER_ERROR.toString()); + renderHtml( + req, + res, + FailureReason.INTERNAL_SERVER_ERROR.getHttpStatusCode(), + FailureReason.INTERNAL_SERVER_ERROR.getMessage()); + } catch (IOException e2) { + e.addSuppressed(e2); + throw e; + } } - if (status != -1) { - res.setStatus(status); - renderHtml(req, res, "gitiles.error", ImmutableMap.of("title", message)); - } + } + + private void renderHtml( + HttpServletRequest req, HttpServletResponse res, int status, String message) + throws IOException { + res.setStatus(status); + renderHtml(req, res, "gitiles.error", ImmutableMap.of("title", message)); } protected void renderHtml(