Skip to content

Commit d1132ad

Browse files
author
David R. MacIver
committed
first pass at getting correct stack traces. This should work for all RPC calls, which is a good chunk of where this is problematic
1 parent 0bdf458 commit d1132ad

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

src/com/rabbitmq/utility/Utility.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,48 @@
3939
*/
4040

4141
public class Utility {
42+
static class ThrowableCreatedElsewhere extends Throwable{
43+
public ThrowableCreatedElsewhere(Throwable throwable){
44+
super(throwable.getClass() + " created elsewhere", throwable.getCause());
45+
this.setStackTrace(throwable.getStackTrace());
46+
}
47+
48+
@Override public Throwable fillInStackTrace(){
49+
return this;
50+
}
51+
}
52+
53+
public static <T extends Throwable> T fixStackTrace(T throwable){
54+
if(throwable.getCause() == null){
55+
// We'd like to preserve the original stack trace in the cause.
56+
// Unfortunately Java doesn't let you set the cause once it's been
57+
// set once. This means we have to choose between either
58+
// - not preserving the type
59+
// - sometimes losing the original stack trace
60+
// - performing nasty reflective voodoo which may or may not work
61+
// We only lose the original stack trace when there's a root cause
62+
// which will hopefully be enlightening enough on its own that it
63+
// doesn't matter too much.
64+
try {
65+
throwable.initCause(new ThrowableCreatedElsewhere(throwable));
66+
} catch(IllegalStateException e){
67+
// This exception was explicitly initialised with a null cause.
68+
// Alas this means we can't set the cause even though it has none.
69+
// Thanks.
70+
}
71+
}
72+
73+
74+
throwable.fillInStackTrace();
75+
// We want to remove fixStackTrace from the trace.
76+
StackTraceElement[] existing = throwable.getStackTrace();
77+
StackTraceElement[] newTrace = new StackTraceElement[existing.length - 1];
78+
for(int i = 0; i < newTrace.length; i++)
79+
newTrace[i] = existing[i + 1];
80+
throwable.setStackTrace(newTrace);
81+
return throwable;
82+
}
83+
4284

4385
public static String makeStackTrace(Throwable throwable) {
4486
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

src/com/rabbitmq/utility/ValueOrException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public V getValue() throws E {
7878
if (_useValue) {
7979
return _value;
8080
} else {
81-
throw _exception;
81+
throw Utility.fixStackTrace(_exception);
8282
}
8383
}
8484
}

0 commit comments

Comments
 (0)