提交 7f4ce02e 编写于 作者: J Jesse Glick

Handle circular references.

上级 187731fd
......@@ -156,6 +156,8 @@ import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import hudson.model.PasswordParameterDefinition;
import hudson.util.RunList;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
......@@ -1453,10 +1455,14 @@ public class Functions {
return Messages.Functions_NoExceptionDetails();
}
StringBuilder s = new StringBuilder();
doPrintStackTrace(s, t, null, "");
doPrintStackTrace(s, t, null, "", new HashSet<Throwable>());
return s.toString();
}
private static void doPrintStackTrace(@Nonnull StringBuilder s, @Nonnull Throwable t, @CheckForNull Throwable higher, @Nonnull String prefix) {
private static void doPrintStackTrace(@Nonnull StringBuilder s, @Nonnull Throwable t, @CheckForNull Throwable higher, @Nonnull String prefix, @Nonnull Set<Throwable> encountered) {
if (!encountered.add(t)) {
s.append("<cycle to ").append(t).append(">\n");
return;
}
if (Util.isOverridden(Throwable.class, t.getClass(), "printStackTrace", PrintWriter.class)) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
......@@ -1465,11 +1471,11 @@ public class Functions {
}
Throwable lower = t.getCause();
if (lower != null) {
doPrintStackTrace(s, lower, t, prefix);
doPrintStackTrace(s, lower, t, prefix, encountered);
}
for (Throwable suppressed : t.getSuppressed()) {
s.append(prefix).append("Also: ");
doPrintStackTrace(s, suppressed, t, prefix + "\t");
doPrintStackTrace(s, suppressed, t, prefix + "\t", encountered);
}
if (lower != null) {
s.append(prefix).append("Caused: ");
......
......@@ -501,6 +501,22 @@ public class FunctionsTest {
s.println("Some custom exception");
}
}, "Some custom exception\n", "Some custom exception\n");
// Circular references:
Stack stack1 = new Stack("p.Exc1", "p.C.method1:17");
Stack stack2 = new Stack("p.Exc2", "p.C.method2:27");
stack1.cause(stack2);
stack2.cause(stack1);
assertPrintThrowable(stack1,
"p.Exc1\n" +
"\tat p.C.method1(C.java:17)\n" +
"Caused by: p.Exc2\n" +
"\tat p.C.method2(C.java:27)\n" +
"\t[CIRCULAR REFERENCE:p.Exc1]\n",
"<cycle to p.Exc1>\n" +
"Caused: p.Exc2\n" +
"\tat p.C.method2(C.java:27)\n" +
"Caused: p.Exc1\n" +
"\tat p.C.method1(C.java:17)\n");
}
private static void assertPrintThrowable(Throwable t, String traditional, String custom) {
StringWriter sw = new StringWriter();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册