From 64676aa13e5c71718caa17bc453b41b05bd41c1e Mon Sep 17 00:00:00 2001 From: seregamorph Date: Tue, 4 Oct 2022 20:40:24 +0200 Subject: [PATCH] GITHUB-2807 - Failsafe buildStackTrace --- CHANGES.txt | 1 + .../main/java/org/testng/internal/Utils.java | 8 +++++++- .../java/org/testng/internal/UtilsTest.java | 20 +++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 4686db82fc..af5e29aa2c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,7 @@ Current New: Ability to provide custom error message for assertThrows\expectThrows methods (Anatolii Yuzhakov) Fixed: GITHUB-2780: Use SpotBugs instead of abandoned FindBugs Fixed: GITHUB-2801: JUnitReportReporter is too slow +Fixed: GITHUB-2807: buildStackTrace should be fail-safe 7.6.1 Fixed: GITHUB-2761: Exception: ERROR java.nio.file.NoSuchFileException: /tmp/testngXmlPathInJar-15086412835569336174 (Krishnan Mahadevan) diff --git a/testng-core-api/src/main/java/org/testng/internal/Utils.java b/testng-core-api/src/main/java/org/testng/internal/Utils.java index b304d78adb..1ee0850721 100644 --- a/testng-core-api/src/main/java/org/testng/internal/Utils.java +++ b/testng-core-api/src/main/java/org/testng/internal/Utils.java @@ -333,7 +333,13 @@ public static String shortStackTrace(Throwable t, boolean toHtml) { private static String buildStackTrace(Throwable t, boolean toHtml, StackTraceType type) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); - t.printStackTrace(pw); + try { + t.printStackTrace(pw); + } catch (Throwable e) { + // failsafe in case if printStackTrace throws exception + pw.println(t.getClass().getName()); + e.printStackTrace(pw); + } pw.flush(); String stackTrace = sw.getBuffer().toString(); if (type == StackTraceType.SHORT && !isTooVerbose()) { diff --git a/testng-core/src/test/java/org/testng/internal/UtilsTest.java b/testng-core/src/test/java/org/testng/internal/UtilsTest.java index cdb3915efc..c2b9726bd3 100644 --- a/testng-core/src/test/java/org/testng/internal/UtilsTest.java +++ b/testng-core/src/test/java/org/testng/internal/UtilsTest.java @@ -2,6 +2,7 @@ import static java.util.Arrays.asList; import static java.util.Collections.emptyList; +import static org.assertj.core.api.Assertions.assertThat; import static org.testng.Assert.assertEquals; import static org.testng.internal.Utils.join; @@ -41,4 +42,23 @@ public void createEmptyStringWhenJoiningEmptyListWithJoinStrings() { List emptyList = emptyList(); assertEquals("", Utils.join(emptyList, ",")); } + + @Test + public void buildStackTraceShouldBeFailsafe() { + // e.g. mocks of Exception classes may throw exception on exception.toString() + RuntimeException ex = new ThrowingException(); + String stackTrace = Utils.longStackTrace(ex, true); + + assertThat(stackTrace) + .contains("org.testng.internal.UtilsTest$ThrowingException") + .contains("java.lang.IllegalStateException: message not available"); + } + + // exception which cannot be printed + private static class ThrowingException extends RuntimeException { + @Override + public String getMessage() { + throw new IllegalStateException("message not available"); + } + } }