Skip to content

Commit fa44e7f

Browse files
Adding support for suppressed exceptions to Throwables.getTrimmedStackTrace().
PiperOrigin-RevId: 745694342
1 parent 35ebb86 commit fa44e7f

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

services/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
**New Features**
1212

13+
* StackTrimmer now reports suppressed exceptions
14+
1315
**Breaking Changes**
1416

1517
**API Changes**

services/events/java/androidx/test/services/events/internal/Throwables.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
/*
2+
* Copyright (C) 2020 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package androidx.test.services.events.internal;
217

318
import java.io.BufferedReader;
@@ -35,6 +50,8 @@ public static String getTrimmedStackTrace(Throwable exception) {
3550

3651
StringBuilder result = new StringBuilder(exception.toString());
3752
appendStackTraceLines(trimmedStackTraceLines, result);
53+
// Throwable.lockedPrintStackTrace prints suppressed exceptions before it prints the cause.
54+
appendStackTraceLines(getSuppressedStackTraceLines(exception), result);
3855
appendStackTraceLines(getCauseStackTraceLines(exception), result);
3956
return result.toString();
4057
}
@@ -63,6 +80,27 @@ private static List<String> getTrimmedStackTraceLines(Throwable exception) {
6380
return Collections.emptyList();
6481
}
6582

83+
private static List<String> getSuppressedStackTraceLines(Throwable exception) {
84+
if (exception.getSuppressed() == null || exception.getSuppressed().length == 0) {
85+
return Collections.emptyList();
86+
}
87+
List<String> lines = new ArrayList<>();
88+
for (Throwable suppressed : exception.getSuppressed()) {
89+
lines.add(
90+
"\tSuppressed: " + suppressed.getClass().getName() + ": " + suppressed.getMessage());
91+
for (String line : getTrimmedStackTraceLines(suppressed)) {
92+
if (line.isEmpty()) {
93+
continue;
94+
}
95+
lines.add("\t" + line);
96+
}
97+
for (String line : getCauseStackTraceLines(suppressed)) {
98+
lines.add("\t" + line);
99+
}
100+
}
101+
return lines;
102+
}
103+
66104
private static List<String> getCauseStackTraceLines(Throwable exception) {
67105
if (exception.getCause() != null) {
68106
String fullTrace = getFullStackTrace(exception);

services/events/javatests/androidx/test/services/events/internal/StackTrimmerTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,28 @@ public void verifyFailureStackTraceIsTruncated() throws Exception {
5757
testResultTraceLength <= MAX_TRACE_SIZE);
5858
}
5959

60+
@Test
61+
public void verifySuppressedExceptionIsRendered() throws Exception {
62+
Throwable example = new Exception("Failing exception");
63+
example.initCause(new RuntimeException("Cause of failing exception"));
64+
Throwable suppressed = new RuntimeException("Suppressed exception");
65+
suppressed.initCause(new RuntimeException("Cause of suppressed exception"));
66+
example.addSuppressed(suppressed);
67+
Failure testFailure = new Failure(Description.EMPTY, example);
68+
69+
// ensure trace contains the current method, but not any of the junit + androidx.test framework
70+
// traces
71+
String trace = StackTrimmer.getTrimmedStackTrace(testFailure);
72+
assertThat(trace).contains("StackTrimmerTest.verifySuppressedExceptionIsRendered");
73+
assertThat(trace).contains("Failing exception");
74+
assertThat(trace).contains("Cause of failing exception");
75+
assertThat(trace).contains("Suppressed exception");
76+
assertThat(trace).contains("Cause of suppressed exception");
77+
// Make sure that nothing crept into the suppressed exception's stack trace, or its cause.
78+
assertThat(trace).doesNotContain("androidx.test.runner.AndroidJUnitRunner.onStart");
79+
assertThat(trace).doesNotContain("org.junit.runners.ParentRunner.run");
80+
}
81+
6082
private static String getVeryLargeString() {
6183
return new String(new char[1000000]);
6284
}

0 commit comments

Comments
 (0)