mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Adapt to deprecation of NestedServletException
This commit is contained in:
parent
6894f561ce
commit
b0f5fb51fc
@ -40,7 +40,6 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
|||||||
import org.springframework.web.method.HandlerMethod;
|
import org.springframework.web.method.HandlerMethod;
|
||||||
import org.springframework.web.servlet.DispatcherServlet;
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
import org.springframework.web.util.NestedServletException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intercepts incoming HTTP requests handled by Spring MVC handlers and records metrics
|
* Intercepts incoming HTTP requests handled by Spring MVC handlers and records metrics
|
||||||
@ -104,13 +103,13 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter {
|
|||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||||
record(timingContext, request, response, unwrapNestedServletException(ex));
|
record(timingContext, request, response, unwrapServletException(ex));
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Throwable unwrapNestedServletException(Throwable ex) {
|
private Throwable unwrapServletException(Throwable ex) {
|
||||||
return (ex instanceof NestedServletException) ? ex.getCause() : ex;
|
return (ex instanceof ServletException) ? ex.getCause() : ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimingContext startAndAttachTimingContext(HttpServletRequest request) {
|
private TimingContext startAndAttachTimingContext(HttpServletRequest request) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2021 the original author or authors.
|
* Copyright 2012-2022 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.
|
||||||
@ -28,6 +28,7 @@ import io.micrometer.core.instrument.MeterRegistry;
|
|||||||
import io.micrometer.core.instrument.MockClock;
|
import io.micrometer.core.instrument.MockClock;
|
||||||
import io.micrometer.core.instrument.simple.SimpleConfig;
|
import io.micrometer.core.instrument.simple.SimpleConfig;
|
||||||
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@ -49,7 +50,6 @@ import org.springframework.web.context.WebApplicationContext;
|
|||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
import org.springframework.web.util.NestedServletException;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
@ -92,8 +92,7 @@ class LongTaskTimingHandlerInterceptorTests {
|
|||||||
MvcResult result = this.mvc.perform(get("/api/c1/completableFutureException"))
|
MvcResult result = this.mvc.perform(get("/api/c1/completableFutureException"))
|
||||||
.andExpect(request().asyncStarted()).andReturn();
|
.andExpect(request().asyncStarted()).andReturn();
|
||||||
assertThat(this.registry.get("my.long.request.exception").longTaskTimer().activeTasks()).isEqualTo(1);
|
assertThat(this.registry.get("my.long.request.exception").longTaskTimer().activeTasks()).isEqualTo(1);
|
||||||
assertThatExceptionOfType(NestedServletException.class)
|
assertThatExceptionOfType(ServletException.class).isThrownBy(() -> this.mvc.perform(asyncDispatch(result)))
|
||||||
.isThrownBy(() -> this.mvc.perform(asyncDispatch(result)))
|
|
||||||
.withRootCauseInstanceOf(RuntimeException.class);
|
.withRootCauseInstanceOf(RuntimeException.class);
|
||||||
assertThat(this.registry.get("my.long.request.exception").longTaskTimer().activeTasks()).isEqualTo(0);
|
assertThat(this.registry.get("my.long.request.exception").longTaskTimer().activeTasks()).isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,6 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
|||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
|
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
|
||||||
import org.springframework.web.util.NestedServletException;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||||
@ -191,7 +190,8 @@ class WebMvcMetricsFilterTests {
|
|||||||
assertThatCode(() -> this.mvc
|
assertThatCode(() -> this.mvc
|
||||||
.perform(get("/api/filterError").header(CustomBehaviorFilter.TEST_SERVLET_EXCEPTION_HEADER, "throw")))
|
.perform(get("/api/filterError").header(CustomBehaviorFilter.TEST_SERVLET_EXCEPTION_HEADER, "throw")))
|
||||||
.isInstanceOf(ServletException.class);
|
.isInstanceOf(ServletException.class);
|
||||||
Id meterId = this.registry.get("http.server.requests").tags("exception", "ServletException").timer().getId();
|
Id meterId = this.registry.get("http.server.requests").tags("exception", "IllegalStateException").timer()
|
||||||
|
.getId();
|
||||||
assertThat(meterId.getTag("status")).isEqualTo("500");
|
assertThat(meterId.getTag("status")).isEqualTo("500");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,8 +253,7 @@ class WebMvcMetricsFilterTests {
|
|||||||
void asyncRequestThatThrowsUncheckedException() throws Exception {
|
void asyncRequestThatThrowsUncheckedException() throws Exception {
|
||||||
MvcResult result = this.mvc.perform(get("/api/c1/completableFutureException"))
|
MvcResult result = this.mvc.perform(get("/api/c1/completableFutureException"))
|
||||||
.andExpect(request().asyncStarted()).andReturn();
|
.andExpect(request().asyncStarted()).andReturn();
|
||||||
assertThatExceptionOfType(NestedServletException.class)
|
assertThatExceptionOfType(ServletException.class).isThrownBy(() -> this.mvc.perform(asyncDispatch(result)))
|
||||||
.isThrownBy(() -> this.mvc.perform(asyncDispatch(result)))
|
|
||||||
.withRootCauseInstanceOf(RuntimeException.class);
|
.withRootCauseInstanceOf(RuntimeException.class);
|
||||||
assertThat(this.registry.get("http.server.requests").tags("uri", "/api/c1/completableFutureException").timer()
|
assertThat(this.registry.get("http.server.requests").tags("uri", "/api/c1/completableFutureException").timer()
|
||||||
.count()).isEqualTo(1);
|
.count()).isEqualTo(1);
|
||||||
@ -553,7 +552,7 @@ class WebMvcMetricsFilterTests {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (request.getHeader(TEST_SERVLET_EXCEPTION_HEADER) != null) {
|
if (request.getHeader(TEST_SERVLET_EXCEPTION_HEADER) != null) {
|
||||||
throw new ServletException();
|
throw new ServletException(new IllegalStateException());
|
||||||
}
|
}
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2021 the original author or authors.
|
* Copyright 2012-2022 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.
|
||||||
@ -22,6 +22,7 @@ import io.micrometer.core.instrument.MeterRegistry;
|
|||||||
import io.micrometer.core.instrument.MockClock;
|
import io.micrometer.core.instrument.MockClock;
|
||||||
import io.micrometer.core.instrument.simple.SimpleConfig;
|
import io.micrometer.core.instrument.simple.SimpleConfig;
|
||||||
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@ -44,7 +45,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
import org.springframework.web.util.NestedServletException;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
@ -86,7 +86,7 @@ class WebMvcMetricsIntegrationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void rethrownExceptionIsRecordedInMetricTag() {
|
void rethrownExceptionIsRecordedInMetricTag() {
|
||||||
assertThatExceptionOfType(NestedServletException.class)
|
assertThatExceptionOfType(ServletException.class)
|
||||||
.isThrownBy(() -> this.mvc.perform(get("/api/rethrownError")).andReturn());
|
.isThrownBy(() -> this.mvc.perform(get("/api/rethrownError")).andReturn());
|
||||||
assertThat(this.registry.get("http.server.requests").tags("exception", "Exception2", "status", "500").timer()
|
assertThat(this.registry.get("http.server.requests").tags("exception", "Exception2", "status", "500").timer()
|
||||||
.count()).isEqualTo(1L);
|
.count()).isEqualTo(1L);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.springframework.boot.test.autoconfigure.web.servlet.mockmvc;
|
package org.springframework.boot.test.autoconfigure.web.servlet.mockmvc;
|
||||||
|
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.validation.ConstraintViolationException;
|
import jakarta.validation.ConstraintViolationException;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@ -24,7 +25,6 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
|||||||
import org.springframework.boot.web.servlet.error.ErrorAttributes;
|
import org.springframework.boot.web.servlet.error.ErrorAttributes;
|
||||||
import org.springframework.security.test.context.support.WithMockUser;
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.web.util.NestedServletException;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
@ -70,8 +70,7 @@ class WebMvcTestAllControllersIntegrationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldRunValidationFailure() {
|
void shouldRunValidationFailure() {
|
||||||
assertThatExceptionOfType(NestedServletException.class)
|
assertThatExceptionOfType(ServletException.class).isThrownBy(() -> this.mvc.perform(get("/three/invalid")))
|
||||||
.isThrownBy(() -> this.mvc.perform(get("/three/invalid")))
|
|
||||||
.withCauseInstanceOf(ConstraintViolationException.class);
|
.withCauseInstanceOf(ConstraintViolationException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ import org.springframework.boot.web.server.ErrorPageRegistry;
|
|||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
import org.springframework.web.util.NestedServletException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Servlet {@link Filter} that provides an {@link ErrorPageRegistry} for non-embedded
|
* A Servlet {@link Filter} that provides an {@link ErrorPageRegistry} for non-embedded
|
||||||
@ -133,8 +132,8 @@ public class ErrorPageFilter implements Filter, ErrorPageRegistry, Ordered {
|
|||||||
}
|
}
|
||||||
catch (Throwable ex) {
|
catch (Throwable ex) {
|
||||||
Throwable exceptionToHandle = ex;
|
Throwable exceptionToHandle = ex;
|
||||||
if (ex instanceof NestedServletException) {
|
if (ex instanceof ServletException) {
|
||||||
Throwable rootCause = ((NestedServletException) ex).getRootCause();
|
Throwable rootCause = ((ServletException) ex).getRootCause();
|
||||||
if (rootCause != null) {
|
if (rootCause != null) {
|
||||||
exceptionToHandle = rootCause;
|
exceptionToHandle = rootCause;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,6 @@ 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;
|
||||||
import org.springframework.web.context.request.async.WebAsyncUtils;
|
import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||||
import org.springframework.web.util.NestedServletException;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
@ -367,11 +366,11 @@ class ErrorPageFilterTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void nestedServletExceptionIsUnwrapped() throws Exception {
|
void servletExceptionIsUnwrapped() throws Exception {
|
||||||
this.filter.addErrorPages(new ErrorPage(RuntimeException.class, "/500"));
|
this.filter.addErrorPages(new ErrorPage(RuntimeException.class, "/500"));
|
||||||
this.chain = new TestFilterChain((request, response, chain) -> {
|
this.chain = new TestFilterChain((request, response, chain) -> {
|
||||||
chain.call();
|
chain.call();
|
||||||
throw new NestedServletException("Wrapper", new RuntimeException("BAD"));
|
throw new ServletException("Wrapper", new RuntimeException("BAD"));
|
||||||
});
|
});
|
||||||
this.filter.doFilter(this.request, this.response, this.chain);
|
this.filter.doFilter(this.request, this.response, this.chain);
|
||||||
assertThat(((HttpServletResponseWrapper) this.chain.getResponse()).getStatus()).isEqualTo(500);
|
assertThat(((HttpServletResponseWrapper) this.chain.getResponse()).getStatus()).isEqualTo(500);
|
||||||
@ -388,7 +387,7 @@ class ErrorPageFilterTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void nestedServletExceptionWithNoCause() throws Exception {
|
void servletExceptionWithNoCause() throws Exception {
|
||||||
this.filter.addErrorPages(new ErrorPage(MissingServletRequestParameterException.class, "/500"));
|
this.filter.addErrorPages(new ErrorPage(MissingServletRequestParameterException.class, "/500"));
|
||||||
this.chain = new TestFilterChain((request, response, chain) -> {
|
this.chain = new TestFilterChain((request, response, chain) -> {
|
||||||
chain.call();
|
chain.call();
|
||||||
|
Loading…
Reference in New Issue
Block a user