Commit 26f59126 authored by Andy Wilkinson's avatar Andy Wilkinson

Fix handling of NestedServletException with no root cause

Fixes gh-22169
parent c9958c2a
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -137,7 +137,10 @@ public class ErrorPageFilter implements Filter, ErrorPageRegistry { ...@@ -137,7 +137,10 @@ public class ErrorPageFilter implements Filter, ErrorPageRegistry {
catch (Throwable ex) { catch (Throwable ex) {
Throwable exceptionToHandle = ex; Throwable exceptionToHandle = ex;
if (ex instanceof NestedServletException) { if (ex instanceof NestedServletException) {
exceptionToHandle = ((NestedServletException) ex).getRootCause(); Throwable rootCause = ((NestedServletException) ex).getRootCause();
if (rootCause != null) {
exceptionToHandle = rootCause;
}
} }
handleException(request, response, wrapped, exceptionToHandle); handleException(request, response, wrapped, exceptionToHandle);
response.flushBuffer(); response.flushBuffer();
......
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -42,6 +42,7 @@ import org.springframework.mock.web.MockFilterConfig; ...@@ -42,6 +42,7 @@ import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockRequestDispatcher; import org.springframework.mock.web.MockRequestDispatcher;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.context.request.async.StandardServletAsyncWebRequest; import org.springframework.web.context.request.async.StandardServletAsyncWebRequest;
import org.springframework.web.context.request.async.WebAsyncManager; import org.springframework.web.context.request.async.WebAsyncManager;
...@@ -388,6 +389,30 @@ public class ErrorPageFilterTests { ...@@ -388,6 +389,30 @@ public class ErrorPageFilterTests {
assertThat(this.response.getForwardedUrl()).isEqualTo("/500"); assertThat(this.response.getForwardedUrl()).isEqualTo("/500");
} }
@Test
public void nestedServletExceptionWithNoCause() throws Exception {
this.filter.addErrorPages(new ErrorPage(MissingServletRequestParameterException.class, "/500"));
this.chain = new TestFilterChain((request, response, chain) -> {
chain.call();
throw new MissingServletRequestParameterException("test", "string");
});
this.filter.doFilter(this.request, this.response, this.chain);
assertThat(((HttpServletResponseWrapper) this.chain.getResponse()).getStatus()).isEqualTo(500);
assertThat(this.request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)).isEqualTo(500);
assertThat(this.request.getAttribute(RequestDispatcher.ERROR_MESSAGE))
.isEqualTo("Required string parameter 'test' is not present");
Map<String, Object> requestAttributes = getAttributesForDispatch("/500");
assertThat(requestAttributes.get(RequestDispatcher.ERROR_EXCEPTION_TYPE))
.isEqualTo(MissingServletRequestParameterException.class);
assertThat(requestAttributes.get(RequestDispatcher.ERROR_EXCEPTION))
.isInstanceOf(MissingServletRequestParameterException.class);
assertThat(this.request.getAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE)).isNull();
assertThat(this.request.getAttribute(RequestDispatcher.ERROR_EXCEPTION)).isNull();
assertThat(this.request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI)).isEqualTo("/test/path");
assertThat(this.response.isCommitted()).isTrue();
assertThat(this.response.getForwardedUrl()).isEqualTo("/500");
}
@Test @Test
public void whenErrorIsSentAndWriterIsFlushedErrorIsSentToTheClient() throws Exception { public void whenErrorIsSentAndWriterIsFlushedErrorIsSentToTheClient() throws Exception {
this.chain = new TestFilterChain((request, response, chain) -> { this.chain = new TestFilterChain((request, response, chain) -> {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment