Skip to content

Commit

Permalink
Merge pull request #805 from benjchristensen/fix-composite-exception
Browse files Browse the repository at this point in the history
Fix CompositeException
  • Loading branch information
benjchristensen committed Feb 4, 2014
2 parents de1e0b1 + a98b17d commit 267d569
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 3 deletions.
16 changes: 13 additions & 3 deletions rxjava-core/src/main/java/rx/util/CompositeException.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* Exception that is a composite of 1 or more other exceptions.
Expand Down Expand Up @@ -84,9 +86,16 @@ private static String getStackTraceAsString(StackTraceElement[] stack) {
return s.toString();
}

private static void attachCallingThreadStack(Throwable e, Throwable cause) {
/* package-private */ static void attachCallingThreadStack(Throwable e, Throwable cause) {
Set<Throwable> seenCauses = new HashSet<Throwable>();

while (e.getCause() != null) {
e = e.getCause();
if (seenCauses.contains(e.getCause())) {
break;
} else {
seenCauses.add(e.getCause());
}
}
// we now have 'e' as the last in the chain
try {
Expand All @@ -98,12 +107,13 @@ private static void attachCallingThreadStack(Throwable e, Throwable cause) {
}
}

private final static class CompositeExceptionCausalChain extends RuntimeException {
/* package-private */ final static class CompositeExceptionCausalChain extends RuntimeException {
private static final long serialVersionUID = 3875212506787802066L;
/* package-private */ static String MESSAGE = "Chain of Causes for CompositeException In Order Received =>";

@Override
public String getMessage() {
return "Chain of Causes for CompositeException In Order Received =>";
return MESSAGE;
}
}

Expand Down
92 changes: 92 additions & 0 deletions rxjava-core/src/test/java/rx/util/CompositeExceptionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* Copyright 2013 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package rx.util;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.Test;

public class CompositeExceptionTest {

private final Throwable ex1 = new Throwable("Ex1");
private final Throwable ex2 = new Throwable("Ex2", ex1);
private final Throwable ex3 = new Throwable("Ex3", ex2);

public CompositeExceptionTest() {
ex1.initCause(ex2);
}

private CompositeException getNewCompositeExceptionWithEx123() {
List<Throwable> throwables = new ArrayList<Throwable>();
throwables.add(ex1);
throwables.add(ex2);
throwables.add(ex3);
return new CompositeException(throwables);
}

@Test(timeout = 1000)
public void testMultipleWithSameCause() {
Throwable rootCause = new Throwable("RootCause");
Throwable e1 = new Throwable("1", rootCause);
Throwable e2 = new Throwable("2", rootCause);
Throwable e3 = new Throwable("3", rootCause);
CompositeException ce = new CompositeException("3 failures with same root cause", Arrays.asList(e1, e2, e3));
}

@Test(timeout = 1000)
public void testAttachCallingThreadStackParentThenChild() {
CompositeException.attachCallingThreadStack(ex1, ex2);
assertEquals("Ex2", ex1.getCause().getMessage());
}

@Test(timeout = 1000)
public void testAttachCallingThreadStackChildThenParent() {
CompositeException.attachCallingThreadStack(ex2, ex1);
assertEquals("Ex1", ex2.getCause().getMessage());
}

@Test(timeout = 1000)
public void testAttachCallingThreadStackAddComposite() {
CompositeException.attachCallingThreadStack(ex1, getNewCompositeExceptionWithEx123());
assertEquals("Ex2", ex1.getCause().getMessage());
}

@Test(timeout = 1000)
public void testAttachCallingThreadStackAddToComposite() {
CompositeException compositeEx = getNewCompositeExceptionWithEx123();
CompositeException.attachCallingThreadStack(compositeEx, ex1);
assertEquals(CompositeException.CompositeExceptionCausalChain.MESSAGE, compositeEx.getCause().getMessage());
}

@Test(timeout = 1000)
public void testAttachCallingThreadStackAddCompositeToItself() {
CompositeException compositeEx = getNewCompositeExceptionWithEx123();
CompositeException.attachCallingThreadStack(compositeEx, compositeEx);
assertEquals(CompositeException.CompositeExceptionCausalChain.MESSAGE, compositeEx.getCause().getMessage());
}

@Test(timeout = 1000)
public void testAttachCallingThreadStackAddExceptionsToEachOther() {
CompositeException.attachCallingThreadStack(ex1, ex2);
CompositeException.attachCallingThreadStack(ex2, ex1);
assertEquals("Ex2", ex1.getCause().getMessage());
assertEquals("Ex1", ex2.getCause().getMessage());
}
}

0 comments on commit 267d569

Please sign in to comment.