Skip to content

Commit b2b691b

Browse files
committed
Merge branch '2.4.x' into 2.5.x
Closes gh-28069
2 parents 6f555c4 + c2361ae commit b2b691b

File tree

2 files changed

+39
-24
lines changed

2 files changed

+39
-24
lines changed

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilter.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,9 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
103103
record(timingContext, request, response, exception);
104104
}
105105
}
106-
catch (NestedServletException ex) {
106+
catch (Exception ex) {
107107
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
108-
record(timingContext, request, response, ex.getCause());
109-
throw ex;
110-
}
111-
catch (ServletException | IOException | RuntimeException ex) {
112-
record(timingContext, request, response, ex);
108+
record(timingContext, request, response, (ex instanceof NestedServletException) ? ex.getCause() : ex);
113109
throw ex;
114110
}
115111
}

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterTests.java

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import io.micrometer.core.annotation.Timed;
3939
import io.micrometer.core.instrument.Clock;
4040
import io.micrometer.core.instrument.Meter;
41+
import io.micrometer.core.instrument.Meter.Id;
4142
import io.micrometer.core.instrument.MeterRegistry;
4243
import io.micrometer.core.instrument.MockClock;
4344
import io.micrometer.core.instrument.Tag;
@@ -127,8 +128,8 @@ class WebMvcMetricsFilterTests {
127128

128129
@BeforeEach
129130
void setupMockMvc() {
130-
this.mvc = MockMvcBuilders.webAppContextSetup(this.context)
131-
.addFilters(this.filter, new RedirectAndNotFoundFilter()).build();
131+
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).addFilters(this.filter, new CustomBehaviorFilter())
132+
.build();
132133
}
133134

134135
@Test
@@ -165,15 +166,15 @@ void badClientRequest() throws Exception {
165166

166167
@Test
167168
void redirectRequest() throws Exception {
168-
this.mvc.perform(get("/api/redirect").header(RedirectAndNotFoundFilter.TEST_MISBEHAVE_HEADER, "302"))
169+
this.mvc.perform(get("/api/redirect").header(CustomBehaviorFilter.TEST_STATUS_HEADER, "302"))
169170
.andExpect(status().is3xxRedirection());
170171
assertThat(this.registry.get("http.server.requests").tags("uri", "REDIRECTION").tags("status", "302").timer())
171172
.isNotNull();
172173
}
173174

174175
@Test
175176
void notFoundRequest() throws Exception {
176-
this.mvc.perform(get("/api/not/found").header(RedirectAndNotFoundFilter.TEST_MISBEHAVE_HEADER, "404"))
177+
this.mvc.perform(get("/api/not/found").header(CustomBehaviorFilter.TEST_STATUS_HEADER, "404"))
177178
.andExpect(status().is4xxClientError());
178179
assertThat(this.registry.get("http.server.requests").tags("uri", "NOT_FOUND").tags("status", "404").timer())
179180
.isNotNull();
@@ -187,13 +188,23 @@ void unhandledError() {
187188
.isEqualTo(1L);
188189
}
189190

191+
@Test
192+
void unhandledServletException() {
193+
assertThatCode(() -> this.mvc
194+
.perform(get("/api/filterError").header(CustomBehaviorFilter.TEST_SERVLET_EXCEPTION_HEADER, "throw"))
195+
.andExpect(status().isOk())).isInstanceOf(ServletException.class);
196+
Id meterId = this.registry.get("http.server.requests").tags("exception", "ServletException").timer().getId();
197+
assertThat(meterId.getTag("status")).isEqualTo("500");
198+
}
199+
190200
@Test
191201
void streamingError() throws Exception {
192202
MvcResult result = this.mvc.perform(get("/api/c1/streamingError")).andExpect(request().asyncStarted())
193203
.andReturn();
194204
assertThatIOException().isThrownBy(() -> this.mvc.perform(asyncDispatch(result)).andReturn());
195-
assertThat(this.registry.get("http.server.requests").tags("exception", "IOException").timer().count())
196-
.isEqualTo(1L);
205+
Id meterId = this.registry.get("http.server.requests").tags("exception", "IOException").timer().getId();
206+
// Response is committed before error occurs so status is 200 (OK)
207+
assertThat(meterId.getTag("status")).isEqualTo("200");
197208
}
198209

199210
@Test
@@ -209,8 +220,10 @@ void anonymousError() {
209220
}
210221
catch (Throwable ignore) {
211222
}
212-
assertThat(this.registry.get("http.server.requests").tag("uri", "/api/c1/anonymousError/{id}").timer().getId()
213-
.getTag("exception")).endsWith("$1");
223+
Id meterId = this.registry.get("http.server.requests").tag("uri", "/api/c1/anonymousError/{id}").timer()
224+
.getId();
225+
assertThat(meterId.getTag("exception")).endsWith("$1");
226+
assertThat(meterId.getTag("status")).isEqualTo("500");
214227
}
215228

216229
@Test
@@ -359,8 +372,8 @@ public MeterFilterReply accept(@NonNull Meter.Id id) {
359372
}
360373

361374
@Bean
362-
RedirectAndNotFoundFilter redirectAndNotFoundFilter() {
363-
return new RedirectAndNotFoundFilter();
375+
CustomBehaviorFilter redirectAndNotFoundFilter() {
376+
return new CustomBehaviorFilter();
364377
}
365378

366379
@Bean(name = "callableBarrier")
@@ -474,8 +487,10 @@ String alwaysThrowsUnhandledException(@PathVariable Long id) {
474487
}
475488

476489
@GetMapping("/streamingError")
477-
ResponseBodyEmitter streamingError() {
490+
ResponseBodyEmitter streamingError() throws IOException {
478491
ResponseBodyEmitter emitter = new ResponseBodyEmitter();
492+
emitter.send("some data");
493+
emitter.send("some more data");
479494
emitter.completeWithError(new IOException("error while writing to the response"));
480495
return emitter;
481496
}
@@ -526,20 +541,24 @@ String successful(@PathVariable Long id) {
526541

527542
}
528543

529-
static class RedirectAndNotFoundFilter extends OncePerRequestFilter {
544+
static class CustomBehaviorFilter extends OncePerRequestFilter {
545+
546+
static final String TEST_STATUS_HEADER = "x-test-status";
530547

531-
static final String TEST_MISBEHAVE_HEADER = "x-test-misbehave-status";
548+
static final String TEST_SERVLET_EXCEPTION_HEADER = "x-test-servlet-exception";
532549

533550
@Override
534551
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
535552
FilterChain filterChain) throws ServletException, IOException {
536-
String misbehave = request.getHeader(TEST_MISBEHAVE_HEADER);
537-
if (misbehave != null) {
538-
response.setStatus(Integer.parseInt(misbehave));
553+
String misbehaveStatus = request.getHeader(TEST_STATUS_HEADER);
554+
if (misbehaveStatus != null) {
555+
response.setStatus(Integer.parseInt(misbehaveStatus));
556+
return;
539557
}
540-
else {
541-
filterChain.doFilter(request, response);
558+
if (request.getHeader(TEST_SERVLET_EXCEPTION_HEADER) != null) {
559+
throw new ServletException();
542560
}
561+
filterChain.doFilter(request, response);
543562
}
544563

545564
}

0 commit comments

Comments
 (0)