mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Enable logging of resolved exceptions
Previously, if an exception was resolved by a `HandlerExceptionResolver` nothing the log indicated a failure to process the query. This commit adds a new property `spring.mvc.log-resolved-exception` that enables warning logs for supported `HandlerExceptionResolver` instances. When Devtools is enabled, this flag is enabled by default. Closes gh-2176
This commit is contained in:
parent
1175879fcc
commit
5656e83ba9
@ -68,6 +68,7 @@ import org.springframework.web.filter.HiddenHttpMethodFilter;
|
||||
import org.springframework.web.filter.HttpPutFormContentFilter;
|
||||
import org.springframework.web.filter.RequestContextFilter;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.LocaleResolver;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
@ -81,6 +82,7 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
|
||||
import org.springframework.web.servlet.i18n.FixedLocaleResolver;
|
||||
@ -415,6 +417,25 @@ public class WebMvcAutoConfiguration {
|
||||
}
|
||||
return super.createExceptionHandlerExceptionResolver();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureHandlerExceptionResolvers(
|
||||
List<HandlerExceptionResolver> exceptionResolvers) {
|
||||
super.configureHandlerExceptionResolvers(exceptionResolvers);
|
||||
if (exceptionResolvers.isEmpty()) {
|
||||
addDefaultHandlerExceptionResolvers(exceptionResolvers);
|
||||
}
|
||||
if (this.mvcProperties.isLogResolvedException()) {
|
||||
for (HandlerExceptionResolver resolver : exceptionResolvers) {
|
||||
if (resolver instanceof AbstractHandlerExceptionResolver) {
|
||||
((AbstractHandlerExceptionResolver) resolver)
|
||||
.setWarnLogCategory(resolver.getClass()
|
||||
.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
@ -78,6 +78,11 @@ public class WebMvcProperties {
|
||||
*/
|
||||
private boolean throwExceptionIfNoHandlerFound = false;
|
||||
|
||||
/**
|
||||
* Enable warn logging of exceptions resolved by a "HandlerExceptionResolver".
|
||||
*/
|
||||
private boolean logResolvedException = false;
|
||||
|
||||
/**
|
||||
* Maps file extensions to media types for content negotiation, e.g. yml->text/yaml.
|
||||
*/
|
||||
@ -144,6 +149,14 @@ public class WebMvcProperties {
|
||||
this.throwExceptionIfNoHandlerFound = throwExceptionIfNoHandlerFound;
|
||||
}
|
||||
|
||||
public boolean isLogResolvedException() {
|
||||
return this.logResolvedException;
|
||||
}
|
||||
|
||||
public void setLogResolvedException(boolean logResolvedException) {
|
||||
this.logResolvedException = logResolvedException;
|
||||
}
|
||||
|
||||
public Map<String, MediaType> getMediaTypes() {
|
||||
return this.mediaTypes;
|
||||
}
|
||||
|
@ -28,12 +28,14 @@ import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter;
|
||||
@ -58,15 +60,18 @@ import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.filter.HttpPutFormContentFilter;
|
||||
import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.LocaleResolver;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
|
||||
import org.springframework.web.servlet.i18n.FixedLocaleResolver;
|
||||
import org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.servlet.resource.AppCacheManifestTransformer;
|
||||
@ -523,6 +528,37 @@ public class WebMvcAutoConfigurationTests {
|
||||
.isNotInstanceOf(MyRequestMappingHandlerAdapter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultLogResolvedException() {
|
||||
load();
|
||||
testLogResolvedExceptionCustomization(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customLogResolvedException() {
|
||||
load("spring.mvc.log-resolved-exception:true");
|
||||
testLogResolvedExceptionCustomization(true);
|
||||
}
|
||||
|
||||
private void testLogResolvedExceptionCustomization(final boolean expected) {
|
||||
HandlerExceptionResolver exceptionResolver = this.context.getBean(
|
||||
HandlerExceptionResolver.class);
|
||||
assertThat(exceptionResolver).isInstanceOf(HandlerExceptionResolverComposite.class);
|
||||
List<HandlerExceptionResolver> delegates =
|
||||
((HandlerExceptionResolverComposite) exceptionResolver).getExceptionResolvers();
|
||||
for (HandlerExceptionResolver delegate : delegates) {
|
||||
if (delegate instanceof AbstractHandlerMethodAdapter) {
|
||||
assertThat(new DirectFieldAccessor(delegate).getPropertyValue("warnLogger"))
|
||||
.is(new Condition<Object>() {
|
||||
@Override
|
||||
public boolean matches(Object value) {
|
||||
return (expected ? value != null : value == null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void load(Class<?> config, String... environment) {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(this.context, environment);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
* Copyright 2012-2016 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.
|
||||
@ -52,6 +52,7 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro
|
||||
properties.put("spring.h2.console.enabled", "true");
|
||||
properties.put("spring.resources.cache-period", "0");
|
||||
properties.put("spring.template.provider.cache", "false");
|
||||
properties.put("spring.mvc.log-resolved-exception", "true");
|
||||
PROPERTIES = Collections.unmodifiableMap(properties);
|
||||
}
|
||||
|
||||
|
@ -338,6 +338,7 @@ content into your application; rather pick only the properties that you need.
|
||||
spring.mvc.ignore-default-model-on-redirect=true # If the content of the "default" model should be ignored during redirect scenarios.
|
||||
spring.mvc.locale= # Locale to use. By default, this locale is overridden by the "Accept-Language" header.
|
||||
spring.mvc.locale-resolver=accept-header # Define how the locale should be resolved.
|
||||
spring.mvc.log-resolved-exception=false # Enable warn logging of exceptions resolved by a "HandlerExceptionResolver".
|
||||
spring.mvc.media-types.*= # Maps file extensions to media types for content negotiation.
|
||||
spring.mvc.message-codes-resolver-format= # Formatting strategy for message codes. For instance `PREFIX_ERROR_CODE`.
|
||||
spring.mvc.servlet.load-on-startup=-1 # Load on startup priority of the Spring Web Services servlet.
|
||||
|
Loading…
Reference in New Issue
Block a user