diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ErrorProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ErrorProperties.java
index 265b6de8f0..ef155943c7 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ErrorProperties.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ErrorProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2015 the original author or authors.
+ * Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Value;
*
* @author Michael Stummvoll
* @author Stephane Nicoll
+ * @author Vedran Pavic
* @since 1.3.0
*/
public class ErrorProperties {
@@ -33,6 +34,11 @@ public class ErrorProperties {
@Value("${error.path:/error}")
private String path = "/error";
+ /**
+ * Set whether to include the "exception" attribute.
+ */
+ private boolean includeException;
+
/**
* When to include a "stacktrace" attribute.
*/
@@ -46,6 +52,14 @@ public class ErrorProperties {
this.path = path;
}
+ public boolean isIncludeException() {
+ return this.includeException;
+ }
+
+ public void setIncludeException(boolean includeException) {
+ this.includeException = includeException;
+ }
+
public IncludeStacktrace getIncludeStacktrace() {
return this.includeStacktrace;
}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorAttributes.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorAttributes.java
index d378ad48c5..6e4a0a47cc 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorAttributes.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorAttributes.java
@@ -44,7 +44,7 @@ import org.springframework.web.servlet.ModelAndView;
*
timestamp - The time that the errors were extracted
* status - The status code
* error - The error reason
- * exception - The class name of the root exception
+ * exception - The class name of the root exception (if configured)
* message - The exception message
* errors - Any {@link ObjectError}s from a {@link BindingResult} exception
* trace - The exception stack trace
@@ -54,6 +54,7 @@ import org.springframework.web.servlet.ModelAndView;
* @author Phillip Webb
* @author Dave Syer
* @author Stephane Nicoll
+ * @author Vedran Pavic
* @since 1.1.0
* @see ErrorAttributes
*/
@@ -64,6 +65,24 @@ public class DefaultErrorAttributes
private static final String ERROR_ATTRIBUTE = DefaultErrorAttributes.class.getName()
+ ".ERROR";
+ private boolean includeException;
+
+ /**
+ * Create a new {@link DefaultErrorAttributes} instance.
+ * @param includeException whether to include the "exception" attribute
+ */
+ public DefaultErrorAttributes(boolean includeException) {
+ this.includeException = includeException;
+ }
+
+ /**
+ * Create a new {@link DefaultErrorAttributes} instance that does not
+ * include the "exception" attribute.
+ */
+ public DefaultErrorAttributes() {
+ this(false);
+ }
+
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
@@ -117,7 +136,9 @@ public class DefaultErrorAttributes
while (error instanceof ServletException && error.getCause() != null) {
error = ((ServletException) error).getCause();
}
- errorAttributes.put("exception", error.getClass().getName());
+ if (this.includeException) {
+ errorAttributes.put("exception", error.getClass().getName());
+ }
addErrorMessage(errorAttributes, error);
if (includeStackTrace) {
addStackTrace(errorAttributes, error);
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java
index b52a9ba600..c7caf1f4fc 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java
@@ -98,7 +98,8 @@ public class ErrorMvcAutoConfiguration {
@Bean
@ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
public DefaultErrorAttributes errorAttributes() {
- return new DefaultErrorAttributes();
+ return new DefaultErrorAttributes(
+ this.serverProperties.getError().isIncludeException());
}
@Bean
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorAttributesTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorAttributesTests.java
index 7fbdb4624c..1caa0b8723 100644
--- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorAttributesTests.java
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorAttributesTests.java
@@ -41,6 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link DefaultErrorAttributes}.
*
* @author Phillip Webb
+ * @author Vedran Pavic
*/
public class DefaultErrorAttributesTests {
@@ -87,8 +88,7 @@ public class DefaultErrorAttributesTests {
.getErrorAttributes(this.requestAttributes, false);
assertThat(this.errorAttributes.getError(this.requestAttributes)).isSameAs(ex);
assertThat(modelAndView).isNull();
- assertThat(attributes.get("exception"))
- .isEqualTo(RuntimeException.class.getName());
+ assertThat(attributes.get("exception")).isNull();
assertThat(attributes.get("message")).isEqualTo("Test");
}
@@ -99,8 +99,7 @@ public class DefaultErrorAttributesTests {
Map attributes = this.errorAttributes
.getErrorAttributes(this.requestAttributes, false);
assertThat(this.errorAttributes.getError(this.requestAttributes)).isSameAs(ex);
- assertThat(attributes.get("exception"))
- .isEqualTo(RuntimeException.class.getName());
+ assertThat(attributes.get("exception")).isNull();
assertThat(attributes.get("message")).isEqualTo("Test");
}
@@ -120,8 +119,7 @@ public class DefaultErrorAttributesTests {
this.request.setAttribute("javax.servlet.error.message", "Test");
Map attributes = this.errorAttributes
.getErrorAttributes(this.requestAttributes, false);
- assertThat(attributes.get("exception"))
- .isEqualTo(RuntimeException.class.getName());
+ assertThat(attributes.get("exception")).isNull();
assertThat(attributes.get("message")).isEqualTo("Test");
}
@@ -134,8 +132,7 @@ public class DefaultErrorAttributesTests {
.getErrorAttributes(this.requestAttributes, false);
assertThat(this.errorAttributes.getError(this.requestAttributes))
.isSameAs(wrapped);
- assertThat(attributes.get("exception"))
- .isEqualTo(RuntimeException.class.getName());
+ assertThat(attributes.get("exception")).isNull();
assertThat(attributes.get("message")).isEqualTo("Test");
}
@@ -146,8 +143,7 @@ public class DefaultErrorAttributesTests {
Map attributes = this.errorAttributes
.getErrorAttributes(this.requestAttributes, false);
assertThat(this.errorAttributes.getError(this.requestAttributes)).isSameAs(error);
- assertThat(attributes.get("exception"))
- .isEqualTo(OutOfMemoryError.class.getName());
+ assertThat(attributes.get("exception")).isNull();
assertThat(attributes.get("message")).isEqualTo("Test error");
}
@@ -179,6 +175,18 @@ public class DefaultErrorAttributesTests {
assertThat(attributes.get("errors")).isEqualTo(bindingResult.getAllErrors());
}
+ @Test
+ public void withExceptionAttribute() throws Exception {
+ DefaultErrorAttributes errorAttributes = new DefaultErrorAttributes(true);
+ RuntimeException ex = new RuntimeException("Test");
+ this.request.setAttribute("javax.servlet.error.exception", ex);
+ Map attributes = errorAttributes
+ .getErrorAttributes(this.requestAttributes, false);
+ assertThat(attributes.get("exception"))
+ .isEqualTo(RuntimeException.class.getName());
+ assertThat(attributes.get("message")).isEqualTo("Test");
+ }
+
@Test
public void trace() throws Exception {
RuntimeException ex = new RuntimeException("Test");
diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
index fb79a5db1f..19051acff3 100644
--- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
+++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
@@ -153,6 +153,7 @@ content into your application; rather pick only the properties that you need.
server.connection-timeout= # Time in milliseconds that connectors will wait for another HTTP request before closing the connection. When not set, the connector's container-specific default will be used. Use a value of -1 to indicate no (i.e. infinite) timeout.
server.display-name=application # Display name of the application.
server.max-http-header-size=0 # Maximum size in bytes of the HTTP message header.
+ server.error.include-exception=false # Set whether to include the "exception" attribute.
server.error.include-stacktrace=never # When to include a "stacktrace" attribute.
server.error.path=/error # Path of the error controller.
server.error.whitelabel.enabled=true # Enable the default error page displayed in browsers in case of a server error.