|
34 | 34 | import org.springframework.mock.web.MockHttpServletResponse;
|
35 | 35 |
|
36 | 36 | import static org.assertj.core.api.Assertions.assertThat;
|
| 37 | +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |
37 | 38 | import static org.mockito.ArgumentMatchers.any;
|
38 | 39 | import static org.mockito.BDDMockito.given;
|
| 40 | +import static org.mockito.BDDMockito.willThrow; |
39 | 41 | import static org.mockito.Mockito.mock;
|
40 | 42 | import static org.mockito.Mockito.times;
|
41 | 43 | import static org.mockito.Mockito.verify;
|
@@ -109,6 +111,23 @@ void decorateFiltersWhenDefaultsThenUsesEventName() throws Exception {
|
109 | 111 | assertThat(events.get(1).getName()).isEqualTo("authentication.basic.after");
|
110 | 112 | }
|
111 | 113 |
|
| 114 | + // gh-12787 |
| 115 | + @Test |
| 116 | + void decorateFiltersWhenErrorsThenClosesObservationOnlyOnce() throws Exception { |
| 117 | + ObservationHandler<?> handler = mock(ObservationHandler.class); |
| 118 | + given(handler.supportsContext(any())).willReturn(true); |
| 119 | + ObservationRegistry registry = ObservationRegistry.create(); |
| 120 | + registry.observationConfig().observationHandler(handler); |
| 121 | + ObservationFilterChainDecorator decorator = new ObservationFilterChainDecorator(registry); |
| 122 | + FilterChain chain = mock(FilterChain.class); |
| 123 | + Filter filter = mock(Filter.class); |
| 124 | + willThrow(IllegalArgumentException.class).given(filter).doFilter(any(), any(), any()); |
| 125 | + FilterChain decorated = decorator.decorate(chain, List.of(filter)); |
| 126 | + assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy( |
| 127 | + () -> decorated.doFilter(new MockHttpServletRequest("GET", "/"), new MockHttpServletResponse())); |
| 128 | + verify(handler).onScopeClosed(any()); |
| 129 | + } |
| 130 | + |
112 | 131 | private static class BasicAuthenticationFilter implements Filter {
|
113 | 132 |
|
114 | 133 | @Override
|
|
0 commit comments