This is an automated email from the ASF dual-hosted git repository.
vy pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/2.x by this push:
new d46918c9e3 Take `Throwable#toString()` into account while rendering
stack traces in Pattern Layout (#4033)
d46918c9e3 is described below
commit d46918c9e350ba64f1c4af25aea3758c36453b33
Author: JongminChung <[email protected]>
AuthorDate: Thu Mar 5 22:51:59 2026 +0900
Take `Throwable#toString()` into account while rendering stack traces in
Pattern Layout (#4033)
Signed-off-by: Jongmin Chung <[email protected]>
Co-authored-by: Volkan Yazıcı <[email protected]>
---
.../log4j/core/EventParameterMemoryLeakTest.java | 7 ++--
.../pattern/ThrowablePatternConverterTest.java | 37 ++++++++++++++++++++--
.../core/pattern/ThrowableStackTraceRenderer.java | 7 +---
.../.2.x.x/4033_fix_custom_throwable_to_sting.xml | 13 ++++++++
4 files changed, 51 insertions(+), 13 deletions(-)
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/EventParameterMemoryLeakTest.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/EventParameterMemoryLeakTest.java
index ff08d2b2cf..d8b1d90cf2 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/EventParameterMemoryLeakTest.java
+++
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/EventParameterMemoryLeakTest.java
@@ -59,11 +59,8 @@ class EventParameterMemoryLeakTest {
assertThat(messages).hasSize(4);
assertThat(messages.get(0)).isEqualTo("Message with parameter
%s", parameter.value);
assertThat(messages.get(1)).isEqualTo(parameter.value);
- assertThat(messages.get(2))
- .startsWith(String.format("test%n%s: %s",
ObjectThrowable.class.getName(), parameter.value));
- assertThat(messages.get(3))
- .startsWith(
- String.format("test hello%n%s: %s",
ObjectThrowable.class.getName(), parameter.value));
+
assertThat(messages.get(2)).startsWith(String.format("test%n%s", new
ObjectThrowable(parameter)));
+ assertThat(messages.get(3)).startsWith(String.format("test
hello%n%s", new ObjectThrowable(parameter)));
// Return the GC subject
return parameter;
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverterTest.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverterTest.java
index ea9294e58a..0ce38d0323 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverterTest.java
+++
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverterTest.java
@@ -79,6 +79,23 @@ public class ThrowablePatternConverterTest {
}
}
+ /**
+ * Test exception whose {@link #toString()} is intentionally overridden to
return a fixed value.
+ */
+ private static final class ToStringOverridingException extends
RuntimeException {
+
+ private static final ToStringOverridingException INSTANCE = new
ToStringOverridingException();
+
+ private ToStringOverridingException() {
+ super(EXCEPTION);
+ }
+
+ @Override
+ public String toString() {
+ return "foo";
+ }
+ }
+
static Stream<SeparatorTestCase> separatorTestCases() {
final String level = LEVEL.toString();
return Stream.of(
@@ -214,6 +231,14 @@ public class ThrowablePatternConverterTest {
assertThat(actualStackTrace).as("pattern=`%s`",
effectivePattern).isEqualTo(expectedStackTrace);
}
+ @Test
+ void full_output_should_use_custom_toString() {
+ final Throwable exception = ToStringOverridingException.INSTANCE;
+ final String expectedStackTrace =
renderStackTraceUsingJava(exception);
+ final String actualStackTrace = convert(patternPrefix, exception);
+ assertThat(actualStackTrace).isEqualTo(expectedStackTrace);
+ }
+
// This test does not provide `separator` and `suffix` options, since
the reference output will be obtained from
// `Throwable#printStackTrace()`, which doesn't take these into
account.
@ParameterizedTest
@@ -252,10 +277,14 @@ public class ThrowablePatternConverterTest {
}
private String renderStackTraceUsingJava() {
+ return renderStackTraceUsingJava(EXCEPTION);
+ }
+
+ private String renderStackTraceUsingJava(final Throwable throwable) {
final Charset charset = StandardCharsets.UTF_8;
try (final ByteArrayOutputStream outputStream = new
ByteArrayOutputStream();
final PrintStream printStream = new
PrintStream(outputStream, false, charset.name())) {
- EXCEPTION.printStackTrace(printStream);
+ throwable.printStackTrace(printStream);
printStream.flush();
return new String(outputStream.toByteArray(), charset);
} catch (final Exception error) {
@@ -545,9 +574,13 @@ public class ThrowablePatternConverterTest {
}
static String convert(final String pattern) {
+ return convert(pattern, EXCEPTION);
+ }
+
+ private static String convert(final String pattern, final Throwable
throwable) {
final List<PatternFormatter> patternFormatters =
PATTERN_PARSER.parse(pattern, false, true, true);
final LogEvent logEvent =
-
Log4jLogEvent.newBuilder().setThrown(EXCEPTION).setLevel(LEVEL).build();
+
Log4jLogEvent.newBuilder().setThrown(throwable).setLevel(LEVEL).build();
final StringBuilder buffer = new StringBuilder();
for (final PatternFormatter patternFormatter : patternFormatters) {
patternFormatter.format(logEvent, buffer);
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowableStackTraceRenderer.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowableStackTraceRenderer.java
index 885d7de36e..4d21021321 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowableStackTraceRenderer.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowableStackTraceRenderer.java
@@ -138,12 +138,7 @@ class ThrowableStackTraceRenderer<C extends
ThrowableStackTraceRenderer.Context>
}
static void renderThrowableMessage(final StringBuilder buffer, final
Throwable throwable) {
- final String message = throwable.getLocalizedMessage();
- buffer.append(throwable.getClass().getName());
- if (message != null) {
- buffer.append(": ");
- buffer.append(message);
- }
+ buffer.append(throwable);
}
final void renderStackTraceElements(
diff --git a/src/changelog/.2.x.x/4033_fix_custom_throwable_to_sting.xml
b/src/changelog/.2.x.x/4033_fix_custom_throwable_to_sting.xml
new file mode 100644
index 0000000000..761380f81c
--- /dev/null
+++ b/src/changelog/.2.x.x/4033_fix_custom_throwable_to_sting.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
+ type="changed">
+ <issue id="3623"
link="https://github.com/apache/logging-log4j2/issues/3623"/>
+ <issue id="4033"
link="https://github.com/apache/logging-log4j2/pull/4033"/>
+ <description format="asciidoc">
+ Take `Throwable#toString()` into account while rendering stack traces
in Pattern Layout.
+ </description>
+</entry>