Skip to content

1.x: Use the correct Throwable to set the cause for CompositeException #3977

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions src/main/java/rx/exceptions/CompositeException.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,12 @@ public synchronized Throwable getCause() {
// we now have 'e' as the last in the chain
try {
chain.initCause(e);
chain = chain.getCause();
} catch (Throwable t) {
// ignore
// the javadocs say that some Throwables (depending on how they're made) will never
// let me call initCause without blowing up even if it returns null
chain = e;
}
chain = getRootCause(chain);
}
cause = _cause;
}
Expand Down Expand Up @@ -280,17 +279,39 @@ public String getMessage() {
private List<Throwable> getListOfCauses(Throwable ex) {
List<Throwable> list = new ArrayList<Throwable>();
Throwable root = ex.getCause();
if (root == null) {
if (root == null || root == ex) {
return list;
} else {
while(true) {
list.add(root);
if (root.getCause() == null) {
Throwable cause = root.getCause();
if (cause == null || cause == root) {
return list;
} else {
root = root.getCause();
}
}
}
}

/**
* Returns the root cause of {@code e}. If {@code e.getCause()} returns {@null} or {@code e}, just return {@code e} itself.
*
* @param e the {@link Throwable} {@code e}.
* @return The root cause of {@code e}. If {@code e.getCause()} returns {@null} or {@code e}, just return {@code e} itself.
*/
private Throwable getRootCause(Throwable e) {
Throwable root = e.getCause();
if (root == null || root == e) {
return e;
} else {
while(true) {
Throwable cause = root.getCause();
if (cause == null || cause == root) {
return root;
}
root = root.getCause();
}
}
}
}
37 changes: 37 additions & 0 deletions src/test/java/rx/exceptions/CompositeExceptionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

import org.junit.Test;

import rx.exceptions.CompositeException.CompositeExceptionCausalChain;

public class CompositeExceptionTest {

private final Throwable ex1 = new Throwable("Ex1");
Expand Down Expand Up @@ -239,4 +241,39 @@ public void messageVarargs() {
CompositeException compositeException = new CompositeException(ex1, ex2, ex3);
assertEquals("3 exceptions occurred. ", compositeException.getMessage());
}

@Test
public void complexCauses() {
Throwable e1 = new Throwable("1");
Throwable e2 = new Throwable("2");
e1.initCause(e2);

Throwable e3 = new Throwable("3");
Throwable e4 = new Throwable("4");
e3.initCause(e4);

Throwable e5 = new Throwable("5");
Throwable e6 = new Throwable("6");
e5.initCause(e6);

CompositeException compositeException = new CompositeException(e1, e3, e5);
assert(compositeException.getCause() instanceof CompositeExceptionCausalChain);

List<Throwable> causeChain = new ArrayList<Throwable>();
Throwable cause = compositeException.getCause().getCause();
while (cause != null) {
causeChain.add(cause);
cause = cause.getCause();
}
// The original relations
//
// e1 -> e2
// e3 -> e4
// e5 -> e6
//
// will be set to
//
// e1 -> e2 -> e3 -> e4 -> e5 -> e6
assertEquals(Arrays.asList(e1, e2, e3, e4, e5, e6), causeChain);
}
}