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 <masayasuzuki@google.com>
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(