Catch exceptions thrown during String format when collecting diagnostics

Registers the LoggingLinesWriter only if debug logging is actually
enabled.

Closes gh-40500
This commit is contained in:
Moritz Halbritter 2024-04-25 10:40:54 +02:00
parent 8be85611e0
commit 2e906c4720
3 changed files with 37 additions and 4 deletions

View File

@ -52,6 +52,7 @@ import org.springframework.web.context.WebApplicationContext;
*
* @author Phillip Webb
* @author Andy Wilkinson
* @author Moritz Halbritter
* @since 1.4.0
*/
public class SpringBootMockMvcBuilderCustomizer implements MockMvcBuilderCustomizer {
@ -100,7 +101,7 @@ public class SpringBootMockMvcBuilderCustomizer implements MockMvcBuilderCustomi
return null;
}
if (this.print == MockMvcPrint.LOG_DEBUG) {
return new LoggingLinesWriter();
return (LoggingLinesWriter.isDebugEnabled()) ? new LoggingLinesWriter() : null;
}
return new SystemLinesWriter(this.print);
}
@ -192,7 +193,12 @@ public class SpringBootMockMvcBuilderCustomizer implements MockMvcBuilderCustomi
if (value != null && value.getClass().isArray()) {
value = CollectionUtils.arrayToList(value);
}
this.lines.add(String.format("%17s = %s", label, value));
try {
this.lines.add("%17s = %s".formatted(label, value));
}
catch (RuntimeException ex) {
this.lines.add("%17s = << Exception '%s' occurred while formatting >>".formatted(label, ex));
}
}
List<String> getLines() {
@ -277,6 +283,10 @@ public class SpringBootMockMvcBuilderCustomizer implements MockMvcBuilderCustomi
}
}
static boolean isDebugEnabled() {
return logger.isDebugEnabled();
}
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2024 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.
@ -20,11 +20,14 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.WebRequest;
/**
* Example {@link Controller @Controller} used with {@link WebMvcTest @WebMvcTest} tests.
*
* @author Phillip Webb
* @author Moritz Halbritter
*/
@RestController
public class ExampleController1 {
@ -44,4 +47,16 @@ public class ExampleController1 {
return "<html><body>Hello</body></html>";
}
@GetMapping("/formatting")
public String formatting(WebRequest request) {
Object formattingFails = new Object() {
@Override
public String toString() {
throw new IllegalStateException("Formatting failed");
}
};
request.setAttribute("attribute-1", formattingFails, RequestAttributes.SCOPE_SESSION);
return "formatting";
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2024 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.
@ -41,6 +41,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* {@link AutoConfigureMockMvc @AutoConfigureMockMvc} (i.e. full integration test).
*
* @author Phillip Webb
* @author Moritz Halbritter
*/
@SpringBootTest
@AutoConfigureMockMvc(print = MockMvcPrint.SYSTEM_ERR, printOnlyOnFailure = false)
@ -83,4 +84,11 @@ class MockMvcSpringBootTestIntegrationTests {
webTestClient.get().uri("/one").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("one");
}
@Test
void shouldNotFailIfFormattingValueThrowsException(CapturedOutput output) throws Exception {
this.mvc.perform(get("/formatting")).andExpect(content().string("formatting")).andExpect(status().isOk());
assertThat(output).contains(
"Session Attrs = << Exception 'java.lang.IllegalStateException: Formatting failed' occurred while formatting >>");
}
}