From 261168476c9ef0847c7efeaa2a3695e93a33e30c Mon Sep 17 00:00:00 2001
From: Ben Christensen <benjchristensen@netflix.com>
Date: Wed, 31 Jul 2013 20:50:38 -0700
Subject: [PATCH 1/8] Remove assertTrustedObservable

- Was no longer working once onError(Exception) changed to onError(Throwable) as the assertions throwing java.lang.Error no longer bypassed the composed Observables.
- It was confusing while locally contextual JUnit verifications as used everywhere else are clear, readable and localized to each test
---
 .../main/java/rx/operators/OperationTake.java |  32 ++-
 .../java/rx/operators/OperatorTester.java     | 227 ------------------
 2 files changed, 27 insertions(+), 232 deletions(-)

diff --git a/rxjava-core/src/main/java/rx/operators/OperationTake.java b/rxjava-core/src/main/java/rx/operators/OperationTake.java
index 43f51239bc..baefcbf8f3 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationTake.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationTake.java
@@ -158,7 +158,7 @@ public static class UnitTest {
         @Test
         public void testTake1() {
             Observable<String> w = Observable.from("one", "two", "three");
-            Observable<String> take = Observable.create(assertTrustedObservable(take(w, 2)));
+            Observable<String> take = Observable.create(take(w, 2));
 
             @SuppressWarnings("unchecked")
             Observer<String> aObserver = mock(Observer.class);
@@ -173,7 +173,7 @@ public void testTake1() {
         @Test
         public void testTake2() {
             Observable<String> w = Observable.from("one", "two", "three");
-            Observable<String> take = Observable.create(assertTrustedObservable(take(w, 1)));
+            Observable<String> take = Observable.create(take(w, 1));
 
             @SuppressWarnings("unchecked")
             Observer<String> aObserver = mock(Observer.class);
@@ -197,7 +197,17 @@ public Subscription call(Observer<String> observer)
                     return Subscriptions.empty();
                 }
             });
-            Observable.create(assertTrustedObservable(take(source, 1))).toBlockingObservable().last();
+
+            @SuppressWarnings("unchecked")
+            Observer<String> aObserver = mock(Observer.class);
+
+            Observable.create(take(source, 1)).subscribe(aObserver);
+
+            verify(aObserver, times(1)).onNext("one");
+            // even though onError is called we take(1) so shouldn't see it
+            verify(aObserver, never()).onError(any(Throwable.class));
+            verify(aObserver, times(1)).onCompleted();
+            verifyNoMoreInteractions(aObserver);
         }
 
         @Test
@@ -221,9 +231,19 @@ public void unsubscribe()
                     };
                 }
             });
-            Observable.create(assertTrustedObservable(take(source, 0))).toBlockingObservable().lastOrDefault("ok");
+
+            @SuppressWarnings("unchecked")
+            Observer<String> aObserver = mock(Observer.class);
+
+            Observable.create(take(source, 0)).subscribe(aObserver);
             assertTrue("source subscribed", subscribed.get());
             assertTrue("source unsubscribed", unSubscribed.get());
+
+            verify(aObserver, never()).onNext(anyString());
+            // even though onError is called we take(0) so shouldn't see it
+            verify(aObserver, never()).onError(any(Throwable.class));
+            verify(aObserver, times(1)).onCompleted();
+            verifyNoMoreInteractions(aObserver);
         }
 
         @Test
@@ -233,7 +253,7 @@ public void testUnsubscribeAfterTake() {
 
             @SuppressWarnings("unchecked")
             Observer<String> aObserver = mock(Observer.class);
-            Observable<String> take = Observable.create(assertTrustedObservable(take(w, 1)));
+            Observable<String> take = Observable.create(take(w, 1));
             take.subscribe(aObserver);
 
             // wait for the Observable to complete
@@ -248,7 +268,9 @@ public void testUnsubscribeAfterTake() {
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, never()).onNext("two");
             verify(aObserver, never()).onNext("three");
+            verify(aObserver, times(1)).onCompleted();
             verify(s, times(1)).unsubscribe();
+            verifyNoMoreInteractions(aObserver);
         }
 
         private static class TestObservable extends Observable<String> {
diff --git a/rxjava-core/src/main/java/rx/operators/OperatorTester.java b/rxjava-core/src/main/java/rx/operators/OperatorTester.java
index db102cc482..22283673d5 100644
--- a/rxjava-core/src/main/java/rx/operators/OperatorTester.java
+++ b/rxjava-core/src/main/java/rx/operators/OperatorTester.java
@@ -55,18 +55,6 @@ private OperatorTester() {
 
     public static class UnitTest {
 
-        public static <T> Func1<Observer<T>, Subscription> assertTrustedObservable(final Func1<Observer<T>, Subscription> source)
-        {
-            return new Func1<Observer<T>, Subscription>()
-            {
-                @Override
-                public Subscription call(Observer<T> observer)
-                {
-                    return source.call(new TestingObserver<T>(observer));
-                }
-            };
-        }
-
         /**
          * Used for mocking of Schedulers since many Scheduler implementations are static/final.
          * 
@@ -77,221 +65,6 @@ public static Scheduler forwardingScheduler(Scheduler underlying) {
             return new ForwardingScheduler(underlying);
         }
 
-        public static class TestingObserver<T> implements Observer<T> {
-
-            private final Observer<T> actual;
-            private final AtomicBoolean isFinished = new AtomicBoolean(false);
-            private final AtomicBoolean isInCallback = new AtomicBoolean(false);
-
-            public TestingObserver(Observer<T> actual) {
-                this.actual = actual;
-            }
-
-            @Override
-            public void onCompleted() {
-                assertFalse("previous call to onCompleted() or onError()", !isFinished.compareAndSet(false, true));
-                assertFalse("concurrent callback pending", !isInCallback.compareAndSet(false, true));
-                actual.onCompleted();
-                isInCallback.set(false);
-            }
-
-            @Override
-            public void onError(Exception e) {
-                assertFalse("previous call to onCompleted() or onError()", !isFinished.compareAndSet(false, true));
-                assertFalse("concurrent callback pending", !isInCallback.compareAndSet(false, true));
-                actual.onError(e);
-                isInCallback.set(false);
-            }
-
-            @Override
-            public void onNext(T args) {
-                assertFalse("previous call to onCompleted() or onError()", isFinished.get());
-                assertFalse("concurrent callback pending", !isInCallback.compareAndSet(false, true));
-                actual.onNext(args);
-                isInCallback.set(false);
-            }
-
-        }
-
-        @Test(expected = AssertionError.class)
-        public void testDoubleCompleted() {
-            Observable.create(assertTrustedObservable(new Func1<Observer<String>, Subscription>()
-            {
-                @Override
-                public Subscription call(Observer<String> observer)
-                {
-                    observer.onCompleted();
-                    observer.onCompleted();
-                    return Subscriptions.empty();
-                }
-            })).toBlockingObservable().lastOrDefault("end");
-
-        }
-
-        @Test(expected = AssertionError.class)
-        public void testCompletedError() {
-            Observable.create(assertTrustedObservable(new Func1<Observer<String>, Subscription>()
-            {
-                @Override
-                public Subscription call(Observer<String> observer)
-                {
-                    observer.onCompleted();
-                    observer.onError(new Exception());
-                    return Subscriptions.empty();
-                }
-            })).toBlockingObservable().lastOrDefault("end");
-        }
-
-        @Test(expected = AssertionError.class)
-        public void testCompletedNext() {
-            Observable.create(assertTrustedObservable(new Func1<Observer<String>, Subscription>()
-            {
-                @Override
-                public Subscription call(Observer<String> observer)
-                {
-                    observer.onCompleted();
-                    observer.onNext("one");
-                    return Subscriptions.empty();
-                }
-            })).toBlockingObservable().lastOrDefault("end");
-        }
-
-        @Test(expected = AssertionError.class)
-        public void testErrorCompleted() {
-            Observable.create(assertTrustedObservable(new Func1<Observer<String>, Subscription>()
-            {
-                @Override
-                public Subscription call(Observer<String> observer)
-                {
-                    observer.onError(new Exception());
-                    observer.onCompleted();
-                    return Subscriptions.empty();
-                }
-            })).toBlockingObservable().lastOrDefault("end");
-        }
-
-        @Test(expected = AssertionError.class)
-        public void testDoubleError() {
-            Observable.create(assertTrustedObservable(new Func1<Observer<String>, Subscription>()
-            {
-                @Override
-                public Subscription call(Observer<String> observer)
-                {
-                    observer.onError(new Exception());
-                    observer.onError(new Exception());
-                    return Subscriptions.empty();
-                }
-            })).toBlockingObservable().lastOrDefault("end");
-        }
-
-        @Test(expected = AssertionError.class)
-        public void testErrorNext() {
-            Observable.create(assertTrustedObservable(new Func1<Observer<String>, Subscription>()
-            {
-                @Override
-                public Subscription call(Observer<String> observer)
-                {
-                    observer.onError(new Exception());
-                    observer.onNext("one");
-                    return Subscriptions.empty();
-                }
-            })).toBlockingObservable().lastOrDefault("end");
-        }
-
-        @Test
-        public void testNextCompleted() {
-            Observable.create(assertTrustedObservable(new Func1<Observer<String>, Subscription>()
-            {
-                @Override
-                public Subscription call(Observer<String> observer)
-                {
-                    observer.onNext("one");
-                    observer.onCompleted();
-                    return Subscriptions.empty();
-                }
-            })).toBlockingObservable().lastOrDefault("end");
-        }
-
-        @Test
-        public void testConcurrentNextNext() {
-            final List<Thread> threads = new ArrayList<Thread>();
-            final AtomicReference<Throwable> threadFailure = new AtomicReference<Throwable>();
-            Observable.create(assertTrustedObservable(new Func1<Observer<String>, Subscription>()
-            {
-                @Override
-                public Subscription call(final Observer<String> observer)
-                {
-                    threads.add(new Thread(new Runnable()
-                    {
-                        @Override
-                        public void run()
-                        {
-                            observer.onNext("one");
-                        }
-                    }));
-                    threads.add(new Thread(new Runnable()
-                    {
-                        @Override
-                        public void run()
-                        {
-                            observer.onNext("two");
-                        }
-                    }));
-                    return Subscriptions.empty();
-                }
-            })).subscribe(new SlowObserver());
-            for (Thread thread : threads) {
-                thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler()
-                {
-                    @Override
-                    public void uncaughtException(Thread thread, Throwable throwable)
-                    {
-                        threadFailure.set(throwable);
-                    }
-                });
-                thread.start();
-            }
-            for (Thread thread : threads) {
-                try {
-                    thread.join();
-                } catch (InterruptedException ignored) {
-                }
-            }
-            // Junit seems pretty bad about exposing test failures inside of created threads.
-            assertNotNull("exception thrown by thread", threadFailure.get());
-            assertEquals("class of exception thrown by thread", AssertionError.class, threadFailure.get().getClass());
-        }
-
-        private static class SlowObserver implements Observer<String>
-        {
-            @Override
-            public void onCompleted()
-            {
-                try {
-                    Thread.sleep(10);
-                } catch (InterruptedException ignored) {
-                }
-            }
-
-            @Override
-            public void onError(Exception e)
-            {
-                try {
-                    Thread.sleep(10);
-                } catch (InterruptedException ignored) {
-                }
-            }
-
-            @Override
-            public void onNext(String args)
-            {
-                try {
-                    Thread.sleep(10);
-                } catch (InterruptedException ignored) {
-                }
-            }
-        }
-
         public static class ForwardingScheduler extends Scheduler {
             private final Scheduler underlying;
 

From 52595d32b40dabcd817dcddb1336905d2de315a3 Mon Sep 17 00:00:00 2001
From: Ben Christensen <benjchristensen@netflix.com>
Date: Wed, 31 Jul 2013 20:56:35 -0700
Subject: [PATCH 2/8] Clarify unittest for observeOn with ImmediateScheduler

- spying was removed since it wasn't being used and ImmediateScheduler results in no scheduling being done.
---
 .../src/main/java/rx/operators/OperationObserveOn.java    | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/rxjava-core/src/main/java/rx/operators/OperationObserveOn.java b/rxjava-core/src/main/java/rx/operators/OperationObserveOn.java
index a30fb7210d..080773c32f 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationObserveOn.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationObserveOn.java
@@ -67,14 +67,14 @@ public Subscription call(final Observer<T> observer) {
 
     public static class UnitTest {
 
+        /**
+         * This is testing a no-op path since it uses Schedulers.immediate() which will not do scheduling.
+         */
         @Test
         @SuppressWarnings("unchecked")
         public void testObserveOn() {
-
-            Scheduler scheduler = spy(OperatorTester.UnitTest.forwardingScheduler(Schedulers.immediate()));
-
             Observer<Integer> observer = mock(Observer.class);
-            Observable.create(observeOn(Observable.from(1, 2, 3), scheduler)).subscribe(observer);
+            Observable.create(observeOn(Observable.from(1, 2, 3), Schedulers.immediate())).subscribe(observer);
 
             verify(observer, times(1)).onNext(1);
             verify(observer, times(1)).onNext(2);

From 5b92876d8c30c7f1be7a914fb46e438eb1a26638 Mon Sep 17 00:00:00 2001
From: Ben Christensen <benjchristensen@netflix.com>
Date: Wed, 31 Jul 2013 21:01:45 -0700
Subject: [PATCH 3/8] Change onError(Exception) to onError(Throwable)

See issue "Observer#onError should use Throwable" for background => https://github.com/Netflix/RxJava/issues/296
---
 .../src/main/java/rx/Notification.java        | 14 ++--
 rxjava-core/src/main/java/rx/Observable.java  | 76 +++++++++----------
 rxjava-core/src/main/java/rx/Observer.java    |  2 +-
 .../rx/observables/BlockingObservable.java    | 10 +--
 .../main/java/rx/operators/OperationAll.java  |  4 +-
 .../java/rx/operators/OperationBuffer.java    | 18 ++---
 .../rx/operators/OperationCombineLatest.java  | 42 +++++-----
 .../java/rx/operators/OperationConcat.java    | 30 ++++----
 .../java/rx/operators/OperationDefer.java     |  2 +-
 .../rx/operators/OperationDematerialize.java  | 21 ++++-
 .../java/rx/operators/OperationFilter.java    |  6 +-
 .../java/rx/operators/OperationFinally.java   |  2 +-
 .../java/rx/operators/OperationGroupBy.java   | 18 ++---
 .../java/rx/operators/OperationInterval.java  |  6 +-
 .../main/java/rx/operators/OperationMap.java  | 10 +--
 .../rx/operators/OperationMaterialize.java    |  8 +-
 .../java/rx/operators/OperationMerge.java     | 20 ++---
 .../operators/OperationMergeDelayError.java   | 24 +++---
 .../rx/operators/OperationMostRecent.java     | 16 ++--
 .../java/rx/operators/OperationMulticast.java |  6 +-
 .../main/java/rx/operators/OperationNext.java | 20 ++---
 ...OperationOnErrorResumeNextViaFunction.java | 36 ++++-----
 ...erationOnErrorResumeNextViaObservable.java |  8 +-
 .../rx/operators/OperationOnErrorReturn.java  | 28 +++----
 .../java/rx/operators/OperationSample.java    | 14 ++--
 .../main/java/rx/operators/OperationScan.java | 18 ++---
 .../main/java/rx/operators/OperationSkip.java |  6 +-
 .../java/rx/operators/OperationSwitch.java    | 36 ++++-----
 .../rx/operators/OperationSynchronize.java    | 12 +--
 .../main/java/rx/operators/OperationTake.java | 16 ++--
 .../java/rx/operators/OperationTakeLast.java  |  8 +-
 .../java/rx/operators/OperationTakeUntil.java | 10 +--
 .../java/rx/operators/OperationTakeWhile.java | 18 ++---
 .../java/rx/operators/OperationToFuture.java  |  6 +-
 .../rx/operators/OperationToIterator.java     |  4 +-
 .../OperationToObservableFuture.java          |  2 +-
 .../OperationToObservableIterable.java        |  2 +-
 .../operators/OperationToObservableList.java  | 10 +--
 .../OperationToObservableSortedList.java      |  8 +-
 .../java/rx/operators/OperationWhere.java     |  2 +-
 .../main/java/rx/operators/OperationZip.java  | 44 +++++------
 .../main/java/rx/operators/SafeObserver.java  |  8 +-
 .../java/rx/operators/ScheduledObserver.java  |  4 +-
 .../rx/operators/SynchronizedObserver.java    | 20 ++---
 .../java/rx/plugins/RxJavaErrorHandler.java   |  8 +-
 .../RxJavaObservableExecutionHook.java        | 10 +--
 .../main/java/rx/subjects/AsyncSubject.java   | 12 +--
 .../java/rx/subjects/BehaviorSubject.java     |  8 +-
 .../main/java/rx/subjects/PublishSubject.java | 24 +++---
 .../main/java/rx/subjects/ReplaySubject.java  | 16 ++--
 .../java/rx/subjects/UnsubscribeTester.java   |  6 +-
 .../subscriptions/CompositeSubscription.java  |  6 +-
 .../main/java/rx/util/CompositeException.java | 12 +--
 .../util/OnErrorNotImplementedException.java  |  2 +-
 .../java/rx/util/functions/Functions.java     |  2 +-
 .../java/rx/concurrency/TestSchedulers.java   |  6 +-
 .../java/rx/performance/PerformanceTest.java  |  4 +-
 57 files changed, 403 insertions(+), 388 deletions(-)

diff --git a/rxjava-core/src/main/java/rx/Notification.java b/rxjava-core/src/main/java/rx/Notification.java
index 71f2a3a63c..f1dbef8ad9 100644
--- a/rxjava-core/src/main/java/rx/Notification.java
+++ b/rxjava-core/src/main/java/rx/Notification.java
@@ -23,7 +23,7 @@
 public class Notification<T> {
 
     private final Kind kind;
-    private final Exception exception;
+    private final Throwable exception;
     private final T value;
 
     /**
@@ -44,7 +44,7 @@ public Notification(T value) {
      * @param exception
      *            The exception passed to the onError notification.
      */
-    public Notification(Exception exception) {
+    public Notification(Throwable exception) {
         this.exception = exception;
         this.value = null;
         this.kind = Kind.OnError;
@@ -62,9 +62,9 @@ public Notification() {
     /**
      * Retrieves the exception associated with an onError notification.
      * 
-     * @return The exception associated with an onError notification.
+     * @return Throwable associated with an onError notification.
      */
-    public Exception getException() {
+    public Throwable getThrowable() {
         return exception;
     }
 
@@ -126,7 +126,7 @@ public String toString() {
         if (hasValue())
             str.append(" ").append(getValue());
         if (hasException())
-            str.append(" ").append(getException().getMessage());
+            str.append(" ").append(getThrowable().getMessage());
         str.append("]");
         return str.toString();
     }
@@ -137,7 +137,7 @@ public int hashCode() {
         if (hasValue())
             hash = hash * 31 + getValue().hashCode();
         if (hasException())
-            hash = hash * 31 + getException().hashCode();
+            hash = hash * 31 + getThrowable().hashCode();
         return hash;
     }
 
@@ -154,7 +154,7 @@ public boolean equals(Object obj) {
             return false;
         if (hasValue() && !getValue().equals(notification.getValue()))
             return false;
-        if (hasException() && !getException().equals(notification.getException()))
+        if (hasException() && !getThrowable().equals(notification.getThrowable()))
             return false;
         return true;
     }
diff --git a/rxjava-core/src/main/java/rx/Observable.java b/rxjava-core/src/main/java/rx/Observable.java
index aac823a5cb..876ff5de65 100644
--- a/rxjava-core/src/main/java/rx/Observable.java
+++ b/rxjava-core/src/main/java/rx/Observable.java
@@ -205,14 +205,14 @@ public Subscription subscribe(Observer<T> observer) {
         } catch (OnErrorNotImplementedException e) {
             // special handling when onError is not implemented ... we just rethrow
             throw e;
-        } catch (Exception e) {
+        } catch (Throwable e) {
             // if an unhandled error occurs executing the onSubscribe we will propagate it
             try {
                 observer.onError(hook.onSubscribeError(this, e));
             } catch (OnErrorNotImplementedException e2) {
                 // special handling when onError is not implemented ... we just rethrow
                 throw e2;
-            } catch (Exception e2) {
+            } catch (Throwable e2) {
                 // if this happens it means the onError itself failed (perhaps an invalid function implementation)
                 // so we are unable to propagate the error correctly and will just throw
                 RuntimeException r = new RuntimeException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);
@@ -295,7 +295,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 handleError(e);
                 Object onError = callbacks.get("onError");
                 if (onError != null) {
@@ -344,7 +344,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 handleError(e);
                 throw new OnErrorNotImplementedException(e);
             }
@@ -379,7 +379,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 handleError(e);
                 throw new OnErrorNotImplementedException(e);
             }
@@ -421,7 +421,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 handleError(e);
                 Functions.from(onError).call(e);
             }
@@ -438,7 +438,7 @@ public Subscription subscribe(final Object onNext, final Object onError, Schedul
         return subscribeOn(scheduler).subscribe(onNext, onError);
     }
 
-    public Subscription subscribe(final Action1<T> onNext, final Action1<Exception> onError) {
+    public Subscription subscribe(final Action1<T> onNext, final Action1<Throwable> onError) {
         if (onNext == null) {
             throw new IllegalArgumentException("onNext can not be null");
         }
@@ -459,7 +459,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 handleError(e);
                 onError.call(e);
             }
@@ -472,7 +472,7 @@ public void onNext(T args) {
         });
     }
 
-    public Subscription subscribe(final Action1<T> onNext, final Action1<Exception> onError, Scheduler scheduler) {
+    public Subscription subscribe(final Action1<T> onNext, final Action1<Throwable> onError, Scheduler scheduler) {
         return subscribeOn(scheduler).subscribe(onNext, onError);
     }
 
@@ -504,7 +504,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 handleError(e);
                 Functions.from(onError).call(e);
             }
@@ -521,7 +521,7 @@ public Subscription subscribe(final Object onNext, final Object onError, final O
         return subscribeOn(scheduler).subscribe(onNext, onError, onComplete);
     }
 
-    public Subscription subscribe(final Action1<T> onNext, final Action1<Exception> onError, final Action0 onComplete) {
+    public Subscription subscribe(final Action1<T> onNext, final Action1<Throwable> onError, final Action0 onComplete) {
         if (onNext == null) {
             throw new IllegalArgumentException("onNext can not be null");
         }
@@ -545,7 +545,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 handleError(e);
                 onError.call(e);
             }
@@ -558,7 +558,7 @@ public void onNext(T args) {
         });
     }
 
-    public Subscription subscribe(final Action1<T> onNext, final Action1<Exception> onError, final Action0 onComplete, Scheduler scheduler) {
+    public Subscription subscribe(final Action1<T> onNext, final Action1<Throwable> onError, final Action0 onComplete, Scheduler scheduler) {
         return subscribeOn(scheduler).subscribe(onNext, onError, onComplete);
     }
 
@@ -583,7 +583,7 @@ public <R> ConnectableObservable<R> multicast(Subject<T, R> subject) {
      *
      * @param e
      */
-    private void handleError(Exception e) {
+    private void handleError(Throwable e) {
         // onError should be rare so we'll only fetch when needed
         RxJavaPlugins.getInstance().getErrorHandler().handleError(e);
     }
@@ -618,7 +618,7 @@ public Subscription call(Observer<T> t1) {
      */
     private static class ThrowObservable<T> extends Observable<T> {
 
-        public ThrowObservable(final Exception exception) {
+        public ThrowObservable(final Throwable exception) {
             super(new Func1<Observer<T>, Subscription>() {
 
                 /**
@@ -956,7 +956,7 @@ public static <T> Observable<T> empty() {
      * @return an Observable that invokes the {@link Observer}'s
      *         {@link Observer#onError onError} method when the Observer subscribes to it
      */
-    public static <T> Observable<T> error(Exception exception) {
+    public static <T> Observable<T> error(Throwable exception) {
         return new ThrowObservable<T>(exception);
     }
 
@@ -1767,7 +1767,7 @@ public static <T> Observable<T> never() {
      *            encounters an error
      * @return an Observable, identical to the source Observable with its behavior modified as described
      */
-    public static <T> Observable<T> onErrorResumeNext(final Observable<T> that, final Func1<Exception, Observable<T>> resumeFunction) {
+    public static <T> Observable<T> onErrorResumeNext(final Observable<T> that, final Func1<Throwable, Observable<T>> resumeFunction) {
         return create(OperationOnErrorResumeNextViaFunction.onErrorResumeNextViaFunction(that, resumeFunction));
     }
 
@@ -1800,11 +1800,11 @@ public static <T> Observable<T> onErrorResumeNext(final Observable<T> that, fina
     public static <T> Observable<T> onErrorResumeNext(final Observable<T> that, final Object resumeFunction) {
         @SuppressWarnings("rawtypes")
         final FuncN _f = Functions.from(resumeFunction);
-        return onErrorResumeNext(that, new Func1<Exception, Observable<T>>() {
+        return onErrorResumeNext(that, new Func1<Throwable, Observable<T>>() {
 
             @SuppressWarnings("unchecked")
             @Override
-            public Observable<T> call(Exception e) {
+            public Observable<T> call(Throwable e) {
                 return (Observable<T>) _f.call(e);
             }
         });
@@ -1866,7 +1866,7 @@ public static <T> Observable<T> onErrorResumeNext(final Observable<T> that, fina
      *            would otherwise cause it to invoke {@link Observer#onError onError}
      * @return an Observable, identical to the source Observable with its behavior modified as described
      */
-    public static <T> Observable<T> onErrorReturn(final Observable<T> that, Func1<Exception, T> resumeFunction) {
+    public static <T> Observable<T> onErrorReturn(final Observable<T> that, Func1<Throwable, T> resumeFunction) {
         return create(OperationOnErrorReturn.onErrorReturn(that, resumeFunction));
     }
 
@@ -3537,7 +3537,7 @@ public Observable<T> observeOn(Scheduler scheduler) {
      * @return an Observable that emits the items and notifications embedded in the
      *         {@link Notification} objects emitted by the source Observable
      * @see <a href="http://msdn.microsoft.com/en-us/library/hh229047(v=vs.103).aspx">MSDN: Observable.dematerialize</a>
-     * @throws Exception
+     * @throws Throwable
      *             if the source Observable is not of type {@code Observable<Notification<T>>}.
      */
     @SuppressWarnings("unchecked")
@@ -3571,7 +3571,7 @@ public <T2> Observable<T2> dematerialize() {
      *            encounters an error
      * @return the original Observable, with appropriately modified behavior
      */
-    public Observable<T> onErrorResumeNext(final Func1<Exception, Observable<T>> resumeFunction) {
+    public Observable<T> onErrorResumeNext(final Func1<Throwable, Observable<T>> resumeFunction) {
         return onErrorResumeNext(this, resumeFunction);
     }
 
@@ -3601,11 +3601,11 @@ public Observable<T> onErrorResumeNext(final Func1<Exception, Observable<T>> res
     public Observable<T> onErrorResumeNext(final Object resumeFunction) {
         @SuppressWarnings("rawtypes")
         final FuncN _f = Functions.from(resumeFunction);
-        return onErrorResumeNext(this, new Func1<Exception, Observable<T>>() {
+        return onErrorResumeNext(this, new Func1<Throwable, Observable<T>>() {
 
             @Override
             @SuppressWarnings("unchecked")
-            public Observable<T> call(Exception e) {
+            public Observable<T> call(Throwable e) {
                 return (Observable<T>) _f.call(e);
             }
         });
@@ -3664,7 +3664,7 @@ public Observable<T> onErrorResumeNext(final Observable<T> resumeSequence) {
      *            Observable encounters an error
      * @return the original Observable with appropriately modified behavior
      */
-    public Observable<T> onErrorReturn(Func1<Exception, T> resumeFunction) {
+    public Observable<T> onErrorReturn(Func1<Throwable, T> resumeFunction) {
         return onErrorReturn(this, resumeFunction);
     }
 
@@ -3694,11 +3694,11 @@ public Observable<T> onErrorReturn(Func1<Exception, T> resumeFunction) {
     public Observable<T> onErrorReturn(final Object resumeFunction) {
         @SuppressWarnings("rawtypes")
         final FuncN _f = Functions.from(resumeFunction);
-        return onErrorReturn(this, new Func1<Exception, T>() {
+        return onErrorReturn(this, new Func1<Throwable, T>() {
 
             @Override
             @SuppressWarnings("unchecked")
-            public T call(Exception e) {
+            public T call(Throwable e) {
                 return (T) _f.call(e);
             }
         });
@@ -4376,7 +4376,7 @@ public Subscription call(Observer<String> Observer) {
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, times(1)).onNext("two");
             verify(aObserver, times(1)).onNext("three");
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -4453,7 +4453,7 @@ public void testMaterializeDematerializeChaining() {
 
             verify(observer, times(1)).onNext(1);
             verify(observer, times(1)).onCompleted();
-            verify(observer, times(0)).onError(any(Exception.class));
+            verify(observer, times(0)).onError(any(Throwable.class));
         }
 
         /**
@@ -4467,7 +4467,7 @@ public void testMaterializeDematerializeChaining() {
         public void testCustomObservableWithErrorInObserverAsynchronous() throws InterruptedException {
             final CountDownLatch latch = new CountDownLatch(1);
             final AtomicInteger count = new AtomicInteger();
-            final AtomicReference<Exception> error = new AtomicReference<Exception>();
+            final AtomicReference<Throwable> error = new AtomicReference<Throwable>();
             Observable.create(new Func1<Observer<String>, Subscription>() {
 
                 @Override
@@ -4499,7 +4499,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     error.set(e);
                     System.out.println("error");
                     e.printStackTrace();
@@ -4533,7 +4533,7 @@ public void onNext(String v) {
         @Test
         public void testCustomObservableWithErrorInObserverSynchronous() {
             final AtomicInteger count = new AtomicInteger();
-            final AtomicReference<Exception> error = new AtomicReference<Exception>();
+            final AtomicReference<Throwable> error = new AtomicReference<Throwable>();
             Observable.create(new Func1<Observer<String>, Subscription>() {
 
                 @Override
@@ -4553,7 +4553,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     error.set(e);
                     System.out.println("error");
                     e.printStackTrace();
@@ -4584,7 +4584,7 @@ public void onNext(String v) {
         @Test
         public void testCustomObservableWithErrorInObservableSynchronous() {
             final AtomicInteger count = new AtomicInteger();
-            final AtomicReference<Exception> error = new AtomicReference<Exception>();
+            final AtomicReference<Throwable> error = new AtomicReference<Throwable>();
             Observable.create(new Func1<Observer<String>, Subscription>() {
 
                 @Override
@@ -4601,7 +4601,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     error.set(e);
                     System.out.println("error");
                     e.printStackTrace();
@@ -4803,7 +4803,7 @@ public void call(Object t1) {
 
                 });
                 fail("expected exception");
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 assertEquals("failure", e.getMessage());
             }
         }
@@ -4822,7 +4822,7 @@ public void call(Object t1) {
         @Test
         public void testErrorThrownWithoutErrorHandlerAsynchronous() throws InterruptedException {
             final CountDownLatch latch = new CountDownLatch(1);
-            final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+            final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
             Observable.create(new Func1<Observer<String>, Subscription>() {
 
                 @Override
@@ -4833,7 +4833,7 @@ public Subscription call(final Observer<String> observer) {
                         public void run() {
                             try {
                                 observer.onError(new RuntimeException("failure"));
-                            } catch (Exception e) {
+                            } catch (Throwable e) {
                                 // without an onError handler it has to just throw on whatever thread invokes it
                                 exception.set(e);
                             }
diff --git a/rxjava-core/src/main/java/rx/Observer.java b/rxjava-core/src/main/java/rx/Observer.java
index 2b8b859f95..c18b3d4fde 100644
--- a/rxjava-core/src/main/java/rx/Observer.java
+++ b/rxjava-core/src/main/java/rx/Observer.java
@@ -42,7 +42,7 @@ public interface Observer<T> {
      *
      * @param e
      */
-    public void onError(Exception e);
+    public void onError(Throwable e);
 
     /**
      * Provides the Observer with new data.
diff --git a/rxjava-core/src/main/java/rx/observables/BlockingObservable.java b/rxjava-core/src/main/java/rx/observables/BlockingObservable.java
index 47d0583cfe..2d826a8fea 100644
--- a/rxjava-core/src/main/java/rx/observables/BlockingObservable.java
+++ b/rxjava-core/src/main/java/rx/observables/BlockingObservable.java
@@ -415,7 +415,7 @@ private Subscription protectivelyWrapAndSubscribe(Observer<T> o) {
      * NOTE: This will block even if the Observable is asynchronous.
      * <p>
      * This is similar to {@link #subscribe(Observer)}, but it blocks. Because it blocks it does
-     * not need the {@link Observer#onCompleted()} or {@link Observer#onError(Exception)} methods.
+     * not need the {@link Observer#onCompleted()} or {@link Observer#onError(Throwable)} methods.
      * <p>
      * <img width="640" src="https://github.com/Netflix/RxJava/wiki/images/rx-operators/B.forEach.png">
      * 
@@ -426,7 +426,7 @@ private Subscription protectivelyWrapAndSubscribe(Observer<T> o) {
      */
     public void forEach(final Action1<T> onNext) {
         final CountDownLatch latch = new CountDownLatch(1);
-        final AtomicReference<Exception> exceptionFromOnError = new AtomicReference<Exception>();
+        final AtomicReference<Throwable> exceptionFromOnError = new AtomicReference<Throwable>();
 
         /**
          * Wrapping since raw functions provided by the user are being invoked.
@@ -440,7 +440,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 /*
                  * If we receive an onError event we set the reference on the outer thread
                  * so we can git it and throw after the latch.await().
@@ -483,7 +483,7 @@ public void onNext(T args) {
      * NOTE: This will block even if the Observable is asynchronous.
      * <p>
      * This is similar to {@link #subscribe(Observer)}, but it blocks. Because it blocks it does
-     * not need the {@link Observer#onCompleted()} or {@link Observer#onError(Exception)} methods.
+     * not need the {@link Observer#onCompleted()} or {@link Observer#onError(Throwable)} methods.
      * <p>
      * <img width="640" src="https://github.com/Netflix/RxJava/wiki/images/rx-operators/B.forEach.png">
      * 
@@ -1026,7 +1026,7 @@ public void call(String t1) {
                     }
                 });
                 fail("we expect an exception to be thrown");
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 // do nothing as we expect this
             }
         }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationAll.java b/rxjava-core/src/main/java/rx/operators/OperationAll.java
index 8084b7835e..244122a346 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationAll.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationAll.java
@@ -61,7 +61,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 underlying.onError(e);
             }
 
@@ -139,7 +139,7 @@ public Boolean call(String s) {
         @Test
         @SuppressWarnings("unchecked")
         public void testError() {
-            Exception error = new Exception();
+            Throwable error = new Throwable();
             Observable<String> obs = Observable.error(error);
 
             Observer<Boolean> observer = mock(Observer.class);
diff --git a/rxjava-core/src/main/java/rx/operators/OperationBuffer.java b/rxjava-core/src/main/java/rx/operators/OperationBuffer.java
index f4fa22ab18..f5e6a692a5 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationBuffer.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationBuffer.java
@@ -379,7 +379,7 @@ public void onCompleted() {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             creator.stop();
             buffers.emitAllBuffers();
             observer.onError(e);
@@ -901,7 +901,7 @@ public Subscription call(Observer<String> observer) {
             buffered.subscribe(observer);
 
             Mockito.verify(observer, Mockito.never()).onNext(Mockito.anyListOf(String.class));
-            Mockito.verify(observer, Mockito.never()).onError(Mockito.any(Exception.class));
+            Mockito.verify(observer, Mockito.never()).onError(Mockito.any(Throwable.class));
             Mockito.verify(observer, Mockito.times(1)).onCompleted();
         }
 
@@ -927,7 +927,7 @@ public Subscription call(Observer<String> observer) {
             inOrder.verify(observer, Mockito.times(1)).onNext(list("two", "three", "four"));
             inOrder.verify(observer, Mockito.times(1)).onNext(list("three", "four", "five"));
             inOrder.verify(observer, Mockito.never()).onNext(Mockito.anyListOf(String.class));
-            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Exception.class));
+            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Throwable.class));
             inOrder.verify(observer, Mockito.never()).onCompleted();
         }
 
@@ -953,7 +953,7 @@ public Subscription call(Observer<String> observer) {
             inOrder.verify(observer, Mockito.times(1)).onNext(list("one", "two", "three"));
             inOrder.verify(observer, Mockito.times(1)).onNext(list("four", "five"));
             inOrder.verify(observer, Mockito.never()).onNext(Mockito.anyListOf(String.class));
-            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Exception.class));
+            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Throwable.class));
             inOrder.verify(observer, Mockito.times(1)).onCompleted();
         }
 
@@ -979,7 +979,7 @@ public Subscription call(Observer<String> observer) {
             inOrder.verify(observer, Mockito.times(1)).onNext(list("one", "two"));
             inOrder.verify(observer, Mockito.times(1)).onNext(list("four", "five"));
             inOrder.verify(observer, Mockito.never()).onNext(Mockito.anyListOf(String.class));
-            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Exception.class));
+            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Throwable.class));
             inOrder.verify(observer, Mockito.times(1)).onCompleted();
         }
 
@@ -1011,7 +1011,7 @@ public Subscription call(Observer<String> observer) {
             scheduler.advanceTimeTo(300, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, Mockito.times(1)).onNext(list("five"));
             inOrder.verify(observer, Mockito.never()).onNext(Mockito.anyListOf(String.class));
-            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Exception.class));
+            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Throwable.class));
             inOrder.verify(observer, Mockito.times(1)).onCompleted();
         }
 
@@ -1040,7 +1040,7 @@ public Subscription call(Observer<String> observer) {
             scheduler.advanceTimeTo(201, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, Mockito.times(1)).onNext(list("four", "five"));
             inOrder.verify(observer, Mockito.never()).onNext(Mockito.anyListOf(String.class));
-            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Exception.class));
+            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Throwable.class));
             inOrder.verify(observer, Mockito.times(1)).onCompleted();
         }
 
@@ -1091,7 +1091,7 @@ public Subscription call(Observer<BufferClosing> observer) {
             inOrder.verify(observer, Mockito.times(1)).onNext(list("two", "three"));
             inOrder.verify(observer, Mockito.times(1)).onNext(list("five"));
             inOrder.verify(observer, Mockito.never()).onNext(Mockito.anyListOf(String.class));
-            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Exception.class));
+            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Throwable.class));
             inOrder.verify(observer, Mockito.times(1)).onCompleted();
         }
 
@@ -1133,7 +1133,7 @@ public Subscription call(Observer<BufferClosing> observer) {
             inOrder.verify(observer, Mockito.times(1)).onNext(list("three", "four"));
             inOrder.verify(observer, Mockito.times(1)).onNext(list("five"));
             inOrder.verify(observer, Mockito.never()).onNext(Mockito.anyListOf(String.class));
-            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Exception.class));
+            inOrder.verify(observer, Mockito.never()).onError(Mockito.any(Throwable.class));
             inOrder.verify(observer, Mockito.times(1)).onCompleted();
         }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationCombineLatest.java b/rxjava-core/src/main/java/rx/operators/OperationCombineLatest.java
index dfcf8bcaf0..089a850e99 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationCombineLatest.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationCombineLatest.java
@@ -115,7 +115,7 @@ public void onCompleted() {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             a.error(e);
         }
 
@@ -185,7 +185,7 @@ <T> void complete(CombineObserver<? extends R, ? super T> w) {
         /**
          * Receive error for a Observer. Throw the error up the chain and stop processing.
          */
-        void error(Exception e) {
+        void error(Throwable e) {
             observer.onError(e);
             /* tell all observers to unsubscribe since we had an error */
             stop();
@@ -226,7 +226,7 @@ <T> void next(CombineObserver<? extends R, ? super T> w, T arg) {
             try {
                 R combinedValue = combineLatestFunction.call(argsToCombineLatest);
                 observer.onNext(combinedValue);
-            } catch(Exception ex) {
+            } catch(Throwable ex) {
                 observer.onError(ex);
             }
         }
@@ -433,14 +433,14 @@ public void testAggregatorSimple() {
 
             InOrder inOrder = inOrder(aObserver);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             inOrder.verify(aObserver, times(1)).onNext("helloworld");
 
             a.next(r1, "hello ");
             a.next(r2, "again");
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             inOrder.verify(aObserver, times(1)).onNext("hello again");
 
@@ -476,14 +476,14 @@ public void testAggregatorDifferentSizedResultsWithOnComplete() {
             a.next(r2, "world");
             a.complete(r2);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             verify(aObserver, times(1)).onNext("helloworld");
 
             a.next(r1, "hi");
             a.complete(r1);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("hiworld");
         }
@@ -513,14 +513,14 @@ public void testAggregateMultipleTypes() {
             a.next(r2, "world");
             a.complete(r2);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             verify(aObserver, times(1)).onNext("helloworld");
 
             a.next(r1, "hi");
             a.complete(r1);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("hiworld");
         }
@@ -552,7 +552,7 @@ public void testAggregate3Types() {
             a.next(r2, 2);
             a.next(r3, new int[] { 5, 6, 7 });
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             verify(aObserver, times(1)).onNext("hello2[5, 6, 7]");
         }
@@ -583,7 +583,7 @@ public void testAggregatorsWithDifferentSizesAndTiming() {
             a.next(r1, "three");
             a.next(r2, "A");
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             verify(aObserver, times(1)).onNext("threeA");
 
@@ -599,7 +599,7 @@ public void testAggregatorsWithDifferentSizesAndTiming() {
             verify(aObserver, times(1)).onNext("fourE");
             a.complete(r2);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -627,7 +627,7 @@ public void testAggregatorError() {
             a.next(r1, "hello");
             a.next(r2, "world");
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             verify(aObserver, times(1)).onNext("helloworld");
 
@@ -635,7 +635,7 @@ public void testAggregatorError() {
             a.next(r1, "hello");
             a.next(r2, "again");
 
-            verify(aObserver, times(1)).onError(any(Exception.class));
+            verify(aObserver, times(1)).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             // we don't want to be called again after an error
             verify(aObserver, times(0)).onNext("helloagain");
@@ -665,7 +665,7 @@ public void testAggregatorUnsubscribe() {
             a.next(r1, "hello");
             a.next(r2, "world");
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             verify(aObserver, times(1)).onNext("helloworld");
 
@@ -673,7 +673,7 @@ public void testAggregatorUnsubscribe() {
             a.next(r1, "hello");
             a.next(r2, "again");
 
-            verify(aObserver, times(0)).onError(any(Exception.class));
+            verify(aObserver, times(0)).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             // we don't want to be called again after an error
             verify(aObserver, times(0)).onNext("helloagain");
@@ -707,13 +707,13 @@ public void testAggregatorEarlyCompletion() {
 
             InOrder inOrder = inOrder(aObserver);
             
-            inOrder.verify(aObserver, never()).onError(any(Exception.class));
+            inOrder.verify(aObserver, never()).onError(any(Throwable.class));
             inOrder.verify(aObserver, never()).onCompleted();
             inOrder.verify(aObserver, times(1)).onNext("twoA");
 
             a.complete(r2);
 
-            inOrder.verify(aObserver, never()).onError(any(Exception.class));
+            inOrder.verify(aObserver, never()).onError(any(Throwable.class));
             inOrder.verify(aObserver, times(1)).onCompleted();
             // we shouldn't get this since completed is called before any other onNext calls could trigger this
             inOrder.verify(aObserver, never()).onNext(anyString());
@@ -731,7 +731,7 @@ public void testCombineLatest2Types() {
             Observable<String> w = Observable.create(combineLatest(Observable.from("one", "two"), Observable.from(2, 3, 4), combineLatestFunction));
             w.subscribe(aObserver);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("two2");
             verify(aObserver, times(1)).onNext("two3");
@@ -750,7 +750,7 @@ public void testCombineLatest3TypesA() {
             Observable<String> w = Observable.create(combineLatest(Observable.from("one", "two"), Observable.from(2), Observable.from(new int[] { 4, 5, 6 }), combineLatestFunction));
             w.subscribe(aObserver);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("two2[4, 5, 6]");
         }
@@ -767,7 +767,7 @@ public void testCombineLatest3TypesB() {
             Observable<String> w = Observable.create(combineLatest(Observable.from("one"), Observable.from(2), Observable.from(new int[] { 4, 5, 6 }, new int[] { 7, 8 }), combineLatestFunction));
             w.subscribe(aObserver);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("one2[4, 5, 6]");
             verify(aObserver, times(1)).onNext("one2[7, 8]");
diff --git a/rxjava-core/src/main/java/rx/operators/OperationConcat.java b/rxjava-core/src/main/java/rx/operators/OperationConcat.java
index 0a2706cca9..96504c531a 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationConcat.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationConcat.java
@@ -89,7 +89,7 @@ public void onNext(T item) {
                     observer.onNext(item);
                 }
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     if (completedOrErred.compareAndSet(false, true)) {
                         outerSubscription.unsubscribe();
                         observer.onError(e);
@@ -131,7 +131,7 @@ public void onNext(Observable<T> nextSequence) {
                     }
                 }
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     if (completedOrErred.compareAndSet(false, true)) {
                         if (innerSubscription != null) {
                             innerSubscription.unsubscribe();
@@ -258,7 +258,7 @@ public void testSimpleAsyncConcat() {
                 // wait for async observables to complete
                 o1.t.join();
                 o2.t.join();
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 throw new RuntimeException("failed waiting on threads");
             }
 
@@ -276,7 +276,7 @@ public void testSimpleAsyncConcat() {
          */
         @SuppressWarnings("unchecked")
         @Test
-        public void testNestedAsyncConcat() throws Exception {
+        public void testNestedAsyncConcat() throws Throwable {
             Observer<String> observer = mock(Observer.class);
 
             final TestObservable<String> o1 = new TestObservable<String>("one", "two", "three");
@@ -317,7 +317,7 @@ public void run() {
                                             observer.onNext(o3);
                                         }
 
-                                    } catch (Exception e) {
+                                    } catch (Throwable e) {
                                         observer.onError(e);
                                     } finally {
                                         System.out.println("Done parent Observable");
@@ -349,7 +349,7 @@ public void run() {
                 }
                 System.out.println("Thread2 started ... waiting for it to complete ...");
                 o2.t.join();
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 throw new RuntimeException("failed waiting on threads", e);
             }
 
@@ -366,7 +366,7 @@ public void run() {
             inOrder.verify(observer, never()).onNext("nine");
             // we should not be completed yet
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             // now allow the third
             allowThird.countDown();
@@ -377,7 +377,7 @@ public void run() {
                 }
                 // wait for 3rd to complete
                 o3.t.join();
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 throw new RuntimeException("failed waiting on threads", e);
             }
 
@@ -386,7 +386,7 @@ public void run() {
             inOrder.verify(observer, times(1)).onNext("nine");
 
             inOrder.verify(observer, times(1)).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
         }
 
         @SuppressWarnings("unchecked")
@@ -407,7 +407,7 @@ public void testBlockedObservableOfObservables() {
             try {
                 //Block main thread to allow observables to serve up o1.
                 callOnce.await();
-            } catch (Exception ex) {
+            } catch (Throwable ex) {
                 ex.printStackTrace();
                 fail(ex.getMessage());
             }
@@ -421,7 +421,7 @@ public void testBlockedObservableOfObservables() {
                 // unblock observables so it can serve up o2 and complete
                 okToContinue.countDown();
                 observableOfObservables.t.join();
-            } catch (Exception ex) {
+            } catch (Throwable ex) {
                 ex.printStackTrace();
                 fail(ex.getMessage());
             }
@@ -463,7 +463,7 @@ public void testConcatConcurrentWithInfinity() {
             inOrder.verify(aObserver, times(1)).onNext("three");
             inOrder.verify(aObserver, times(47)).onNext("hello");
             verify(aObserver, times(1)).onCompleted();
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             
  		}
         
@@ -558,7 +558,7 @@ public void testConcatUnsubscribe() {
                 okToContinue.countDown();
                 w1.t.join();
                 w2.t.join();
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 e.printStackTrace();
                 fail(e.getMessage());
             }
@@ -604,7 +604,7 @@ public void testConcatUnsubscribeConcurrent() {
                 okToContinue.countDown();
                 w1.t.join();   
                 w2.t.join();
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 e.printStackTrace();
                 fail(e.getMessage());
             }
@@ -617,7 +617,7 @@ public void testConcatUnsubscribeConcurrent() {
             inOrder.verify(aObserver, never()).onNext("five");
             inOrder.verify(aObserver, never()).onNext("six");
             verify(aObserver, never()).onCompleted();
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
         }
         
         private static class TestObservable<T> extends Observable<T> {
diff --git a/rxjava-core/src/main/java/rx/operators/OperationDefer.java b/rxjava-core/src/main/java/rx/operators/OperationDefer.java
index ab7d05b019..169227f17c 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationDefer.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationDefer.java
@@ -52,7 +52,7 @@ public Subscription call(Observer<T> observer) {
     public static class UnitTest {
         @Test
         @SuppressWarnings("unchecked")
-        public void testDefer() throws Exception {
+        public void testDefer() throws Throwable {
 
             Func0<Observable<String>> factory = mock(Func0.class);
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationDematerialize.java b/rxjava-core/src/main/java/rx/operators/OperationDematerialize.java
index b3b4d95c3f..3d5c2d8392 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationDematerialize.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationDematerialize.java
@@ -65,7 +65,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                 }
 
                 @Override
@@ -75,7 +75,7 @@ public void onNext(Notification<T> value) {
                         observer.onNext(value.getValue());
                         break;
                     case OnError:
-                        observer.onError(value.getException());
+                        observer.onError(value.getThrowable());
                         break;
                     case OnCompleted:
                         observer.onCompleted();
@@ -100,12 +100,27 @@ public void testDematerialize1() {
             verify(aObserver, times(1)).onNext(1);
             verify(aObserver, times(1)).onNext(2);
             verify(aObserver, times(1)).onCompleted();
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
         }
 
         @Test
         @SuppressWarnings("unchecked")
         public void testDematerialize2() {
+            Throwable exception = new Throwable("test");
+            Observable<Integer> observable = Observable.error(exception);
+            Observable<Integer> dematerialize = Observable.create(dematerialize(observable.materialize()));
+
+            Observer<Integer> aObserver = mock(Observer.class);
+            dematerialize.subscribe(aObserver);
+
+            verify(aObserver, times(1)).onError(exception);
+            verify(aObserver, times(0)).onCompleted();
+            verify(aObserver, times(0)).onNext(any(Integer.class));
+        }
+        
+        @Test
+        @SuppressWarnings("unchecked")
+        public void testDematerialize3() {
             Exception exception = new Exception("test");
             Observable<Integer> observable = Observable.error(exception);
             Observable<Integer> dematerialize = Observable.create(dematerialize(observable.materialize()));
diff --git a/rxjava-core/src/main/java/rx/operators/OperationFilter.java b/rxjava-core/src/main/java/rx/operators/OperationFilter.java
index 21dddafed7..1e0b7d6fd9 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationFilter.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationFilter.java
@@ -55,14 +55,14 @@ public void onNext(T value) {
                         if (predicate.call(value)) {
                             observer.onNext(value);
                         }
-                    } catch (Exception ex) {
+                    } catch (Throwable ex) {
                         observer.onError(ex);
                         // this will work if the sequence is asynchronous, it will have no effect on a synchronous observable
                         subscription.unsubscribe();
                     }
                 }
 
-                public void onError(Exception ex) {
+                public void onError(Throwable ex) {
                     observer.onError(ex);
                 }
 
@@ -93,7 +93,7 @@ public Boolean call(String t1) {
             verify(aObserver, Mockito.never()).onNext("one");
             verify(aObserver, times(1)).onNext("two");
             verify(aObserver, Mockito.never()).onNext("three");
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
     }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationFinally.java b/rxjava-core/src/main/java/rx/operators/OperationFinally.java
index 1192e9f3ac..82fcfd4686 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationFinally.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationFinally.java
@@ -91,7 +91,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 try {
                     observer.onError(e);
                 } finally {
diff --git a/rxjava-core/src/main/java/rx/operators/OperationGroupBy.java b/rxjava-core/src/main/java/rx/operators/OperationGroupBy.java
index fdfbb1c733..4a673b6fee 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationGroupBy.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationGroupBy.java
@@ -95,7 +95,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     // we need to propagate to all children I imagine ... we can't just leave all of those Observable/Observers hanging 
                     for (GroupedSubject<K, V> o : groupedObservables.values()) {
                         o.onError(e);
@@ -215,7 +215,7 @@ public void onCompleted() {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             subscribedObserver.get().onError(e);
         }
 
@@ -235,7 +235,7 @@ public void onCompleted() {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             // do nothing            
         }
 
@@ -298,7 +298,7 @@ public void testError() {
 
             final AtomicInteger groupCounter = new AtomicInteger();
             final AtomicInteger eventCounter = new AtomicInteger();
-            final AtomicReference<Exception> error = new AtomicReference<Exception>();
+            final AtomicReference<Throwable> error = new AtomicReference<Throwable>();
 
             grouped.mapMany(new Func1<GroupedObservable<Integer, String>, Observable<String>>() {
 
@@ -321,7 +321,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     e.printStackTrace();
                     error.set(e);
                 }
@@ -365,10 +365,10 @@ public void call(V v) {
         /**
          * Assert that only a single subscription to a stream occurs and that all events are received.
          * 
-         * @throws Exception
+         * @throws Throwable
          */
         @Test
-        public void testGroupedEventStream() throws Exception {
+        public void testGroupedEventStream() throws Throwable {
 
             final AtomicInteger eventCounter = new AtomicInteger();
             final AtomicInteger subscribeCounter = new AtomicInteger();
@@ -432,7 +432,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     e.printStackTrace();
                     latch.countDown();
                 }
@@ -529,7 +529,7 @@ public void onCompleted() {
                         }
 
                         @Override
-                        public void onError(Exception e) {
+                        public void onError(Throwable e) {
                             e.printStackTrace();
                             latch.countDown();
                         }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationInterval.java b/rxjava-core/src/main/java/rx/operators/OperationInterval.java
index a9a46d2bbe..3b0b00ca15 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationInterval.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationInterval.java
@@ -106,7 +106,7 @@ public void testInterval() {
             
             verify(observer, never()).onNext(0L);
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
             
             scheduler.advanceTimeTo(2, TimeUnit.SECONDS);
 
@@ -115,13 +115,13 @@ public void testInterval() {
             inOrder.verify(observer, times(1)).onNext(1L);
             inOrder.verify(observer, never()).onNext(2L);
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
             
             sub.unsubscribe();
             scheduler.advanceTimeTo(4, TimeUnit.SECONDS);
             verify(observer, never()).onNext(2L);
             verify(observer, times(1)).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
         }
     }
 }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationMap.java b/rxjava-core/src/main/java/rx/operators/OperationMap.java
index c6435ae081..85ec5b38b3 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationMap.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationMap.java
@@ -125,7 +125,7 @@ public void onNext(T value) {
             observer.onNext(func.call(value));
         }
 
-        public void onError(Exception ex) {
+        public void onError(Throwable ex) {
             observer.onError(ex);
         }
 
@@ -160,7 +160,7 @@ public String call(Map<String, String> map) {
             }));
             m.subscribe(stringObserver);
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(1)).onNext("OneFirst");
             verify(stringObserver, times(1)).onNext("TwoFirst");
             verify(stringObserver, times(1)).onCompleted();
@@ -202,7 +202,7 @@ public String call(Map<String, String> map) {
             }));
             m.subscribe(stringObserver);
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(1)).onNext("OneFirst");
             verify(stringObserver, times(1)).onNext("TwoFirst");
             verify(stringObserver, times(1)).onNext("ThreeFirst");
@@ -241,7 +241,7 @@ public String call(Map<String, String> map) {
             }));
             m.subscribe(stringObserver);
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(1)).onNext("OneFirst");
             verify(stringObserver, times(1)).onNext("TwoFirst");
             verify(stringObserver, times(1)).onNext("ThreeFirst");
@@ -277,7 +277,7 @@ public String call(String s) {
             verify(stringObserver, never()).onNext("two");
             verify(stringObserver, never()).onNext("three");
             verify(stringObserver, never()).onCompleted();
-            verify(stringObserver, times(1)).onError(any(Exception.class));
+            verify(stringObserver, times(1)).onError(any(Throwable.class));
 
             // we should have only returned 1 value: "one"
             assertEquals(1, c1.get());
diff --git a/rxjava-core/src/main/java/rx/operators/OperationMaterialize.java b/rxjava-core/src/main/java/rx/operators/OperationMaterialize.java
index 279f4202d0..1e22154e14 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationMaterialize.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationMaterialize.java
@@ -70,7 +70,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     observer.onNext(new Notification<T>(e));
                     observer.onCompleted();
                 }
@@ -108,7 +108,7 @@ public void testMaterialize1() {
             assertTrue(Observer.notifications.get(0).isOnNext());
             assertEquals("two", Observer.notifications.get(1).getValue());
             assertTrue(Observer.notifications.get(1).isOnNext());
-            assertEquals(NullPointerException.class, Observer.notifications.get(2).getException().getClass());
+            assertEquals(NullPointerException.class, Observer.notifications.get(2).getThrowable().getClass());
             assertTrue(Observer.notifications.get(2).isOnError());
         }
 
@@ -174,7 +174,7 @@ public void onCompleted() {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             this.onError = true;
         }
 
@@ -206,7 +206,7 @@ public void run() {
                             System.out.println("throwing exception");
                             try {
                                 Thread.sleep(100);
-                            } catch (Exception e) {
+                            } catch (Throwable e) {
 
                             }
                             observer.onError(new NullPointerException());
diff --git a/rxjava-core/src/main/java/rx/operators/OperationMerge.java b/rxjava-core/src/main/java/rx/operators/OperationMerge.java
index 2710141603..c183fe957e 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationMerge.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationMerge.java
@@ -202,7 +202,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 actualObserver.onError(e);
             }
 
@@ -260,7 +260,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 if (!stopped.get()) {
                     if (ourSubscription.stop()) {
                         // this thread 'won' the race to unsubscribe/stop so let's send the error
@@ -318,7 +318,7 @@ public void unsubscribe() {
             Observable<String> m = Observable.create(merge(observableOfObservables));
             m.subscribe(stringObserver);
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(1)).onCompleted();
             verify(stringObserver, times(2)).onNext("hello");
         }
@@ -332,7 +332,7 @@ public void testMergeArray() {
             Observable<String> m = Observable.create(merge(o1, o2));
             m.subscribe(stringObserver);
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(2)).onNext("hello");
             verify(stringObserver, times(1)).onCompleted();
         }
@@ -348,7 +348,7 @@ public void testMergeList() {
             Observable<String> m = Observable.create(merge(listOfObservables));
             m.subscribe(stringObserver);
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(1)).onCompleted();
             verify(stringObserver, times(2)).onNext("hello");
         }
@@ -370,7 +370,7 @@ public void testUnSubscribe() {
             tA.sendOnCompleted();
             tB.sendOnCompleted();
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(1)).onNext("Aone");
             verify(stringObserver, times(1)).onNext("Bone");
             assertTrue(tA.unsubscribed);
@@ -396,13 +396,13 @@ public void testMergeArrayWithThreading() {
                 throw new RuntimeException(e);
             }
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(2)).onNext("hello");
             verify(stringObserver, times(1)).onCompleted();
         }
 
         @Test
-        public void testSynchronizationOfMultipleSequences() throws Exception {
+        public void testSynchronizationOfMultipleSequences() throws Throwable {
             final TestASynchronousObservable o1 = new TestASynchronousObservable();
             final TestASynchronousObservable o2 = new TestASynchronousObservable();
 
@@ -422,7 +422,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     throw new RuntimeException("failed", e);
                 }
 
@@ -604,7 +604,7 @@ public void sendOnNext(String value) {
 
             /* used to simulate subscription */
             @SuppressWarnings("unused")
-            public void sendOnError(Exception e) {
+            public void sendOnError(Throwable e) {
                 observer.onError(e);
             }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationMergeDelayError.java b/rxjava-core/src/main/java/rx/operators/OperationMergeDelayError.java
index b7e7eb0598..a54f193a2f 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationMergeDelayError.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationMergeDelayError.java
@@ -154,7 +154,7 @@ private static final class MergeDelayErrorObservable<T> implements Func1<Observe
         private final ConcurrentHashMap<ChildObserver, ChildObserver> childObservers = new ConcurrentHashMap<ChildObserver, ChildObserver>();
         private final ConcurrentHashMap<ChildObserver, Subscription> childSubscriptions = new ConcurrentHashMap<ChildObserver, Subscription>();
         // onErrors we received that will be delayed until everything is completed and then sent
-        private ConcurrentLinkedQueue<Exception> onErrorReceived = new ConcurrentLinkedQueue<Exception>();
+        private ConcurrentLinkedQueue<Throwable> onErrorReceived = new ConcurrentLinkedQueue<Throwable>();
 
         private MergeDelayErrorObservable(Observable<Observable<T>> sequences) {
             this.sequences = sequences;
@@ -236,7 +236,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 actualObserver.onError(e);
             }
 
@@ -290,7 +290,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 if (!stopped.get()) {
                     onErrorReceived.add(e);
                     // mark this ChildObserver as done
@@ -548,7 +548,7 @@ public void unsubscribe() {
             Observable<String> m = Observable.create(mergeDelayError(observableOfObservables));
             m.subscribe(stringObserver);
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(1)).onCompleted();
             verify(stringObserver, times(2)).onNext("hello");
         }
@@ -562,7 +562,7 @@ public void testMergeArray() {
             Observable<String> m = Observable.create(mergeDelayError(o1, o2));
             m.subscribe(stringObserver);
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(2)).onNext("hello");
             verify(stringObserver, times(1)).onCompleted();
         }
@@ -578,7 +578,7 @@ public void testMergeList() {
             Observable<String> m = Observable.create(mergeDelayError(listOfObservables));
             m.subscribe(stringObserver);
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(1)).onCompleted();
             verify(stringObserver, times(2)).onNext("hello");
         }
@@ -600,7 +600,7 @@ public void testUnSubscribe() {
             tA.sendOnCompleted();
             tB.sendOnCompleted();
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(1)).onNext("Aone");
             verify(stringObserver, times(1)).onNext("Bone");
             assertTrue(tA.unsubscribed);
@@ -626,7 +626,7 @@ public void testMergeArrayWithThreading() {
                 throw new RuntimeException(e);
             }
 
-            verify(stringObserver, never()).onError(any(Exception.class));
+            verify(stringObserver, never()).onError(any(Throwable.class));
             verify(stringObserver, times(2)).onNext("hello");
             verify(stringObserver, times(1)).onCompleted();
         }
@@ -706,7 +706,7 @@ public void sendOnNext(String value) {
 
             /* used to simulate subscription */
             @SuppressWarnings("unused")
-            public void sendOnError(Exception e) {
+            public void sendOnError(Throwable e) {
                 observer.onError(e);
             }
 
@@ -775,7 +775,7 @@ public void run() {
                                 System.out.println("throwing exception");
                                 try {
                                     Thread.sleep(100);
-                                } catch (Exception e) {
+                                } catch (Throwable e) {
 
                                 }
                                 observer.onError(new NullPointerException());
@@ -803,7 +803,7 @@ public void unsubscribe() {
         }
 
         private static class CaptureObserver implements Observer<String> {
-            volatile Exception e;
+            volatile Throwable e;
 
             @Override
             public void onCompleted() {
@@ -811,7 +811,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 this.e = e;
             }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationMostRecent.java b/rxjava-core/src/main/java/rx/operators/OperationMostRecent.java
index 4a14fe325e..ce7e3dbbcc 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationMostRecent.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationMostRecent.java
@@ -68,8 +68,8 @@ public boolean hasNext() {
 
         @Override
         public T next() {
-            if (observer.getException() != null) {
-                throw Exceptions.propagate(observer.getException());
+            if (observer.getThrowable() != null) {
+                throw Exceptions.propagate(observer.getThrowable());
             }
             return observer.getRecentValue();
         }
@@ -83,7 +83,7 @@ public void remove() {
     private static class MostRecentObserver<T> implements Observer<T> {
         private final AtomicBoolean completed = new AtomicBoolean(false);
         private final AtomicReference<T> value;
-        private final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+        private final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
 
         private MostRecentObserver(T value) {
             this.value = new AtomicReference<T>(value);
@@ -95,7 +95,7 @@ public void onCompleted() {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             exception.set(e);
         }
 
@@ -104,15 +104,15 @@ public void onNext(T args) {
             value.set(args);
         }
 
-        public boolean isCompleted() {
+        private boolean isCompleted() {
             return completed.get();
         }
 
-        public Exception getException() {
+        private Throwable getThrowable() {
             return exception.get();
         }
 
-        public T getRecentValue() {
+        private T getRecentValue() {
             return value.get();
         }
 
@@ -182,7 +182,7 @@ public void sendOnNext(String value) {
             }
 
             /* used to simulate subscription */
-            public void sendOnError(Exception e) {
+            public void sendOnError(Throwable e) {
                 observer.onError(e);
             }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationMulticast.java b/rxjava-core/src/main/java/rx/operators/OperationMulticast.java
index ad312fa1dd..8a7db21dda 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationMulticast.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationMulticast.java
@@ -60,7 +60,7 @@ public void onCompleted() {
                         }
 
                         @Override
-                        public void onError(Exception e) {
+                        public void onError(Throwable e) {
                             subject.onError(e);
                         }
 
@@ -185,7 +185,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     // Do nothing
                 }
 
@@ -204,7 +204,7 @@ public void onCompleted() {
                         }
 
                         @Override
-                        public void onError(Exception e) {
+                        public void onError(Throwable e) {
                             // Do nothing
                         }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationNext.java b/rxjava-core/src/main/java/rx/operators/OperationNext.java
index ad72191382..587141b1eb 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationNext.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationNext.java
@@ -109,7 +109,7 @@ public void onCompleted() {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             // ignore
         }
 
@@ -142,7 +142,7 @@ public boolean isCompleted(boolean rethrowExceptionIfExists) {
 
             if (lastItem.isOnError()) {
                 if (rethrowExceptionIfExists) {
-                    throw Exceptions.propagate(lastItem.getException());
+                    throw Exceptions.propagate(lastItem.getThrowable());
                 } else {
                     return true;
                 }
@@ -155,7 +155,7 @@ public T takeNext() throws InterruptedException {
             Notification<T> next = buf.take();
 
             if (next.isOnError()) {
-                throw Exceptions.propagate(next.getException());
+                throw Exceptions.propagate(next.getThrowable());
             }
 
             if (next.isOnCompleted()) {
@@ -172,7 +172,7 @@ public static class UnitTest {
         private final ExecutorService executor = Executors.newSingleThreadExecutor();
 
         @Test
-        public void testNext() throws Exception {
+        public void testNext() throws Throwable {
             Subscription s = mock(Subscription.class);
             final TestObservable obs = new TestObservable(s);
 
@@ -249,13 +249,13 @@ public void testOnErrorViaHasNext() throws Throwable {
             // this should not throw an exception but instead just return false
             try {
                 assertFalse(it.hasNext());
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 fail("should not have received exception");
                 e.printStackTrace();
             }
         }
 
-        private Future<String> nextAsync(final Iterator<String> it) throws Exception {
+        private Future<String> nextAsync(final Iterator<String> it) throws Throwable {
 
             return executor.submit(new Callable<String>() {
 
@@ -286,7 +286,7 @@ public void sendOnNext(String value) {
             }
 
             /* used to simulate subscription */
-            public void sendOnError(Exception e) {
+            public void sendOnError(Throwable e) {
                 observer.onError(e);
             }
 
@@ -308,10 +308,10 @@ private static class TestException extends RuntimeException {
          * 
          * This results in output such as => a: 1 b: 2 c: 89
          * 
-         * @throws Exception
+         * @throws Throwable
          */
         @Test
-        public void testNoBufferingOrBlockingOfSequence() throws Exception {
+        public void testNoBufferingOrBlockingOfSequence() throws Throwable {
             final CountDownLatch finished = new CountDownLatch(1);
             final AtomicBoolean running = new AtomicBoolean(true);
             final AtomicInteger count = new AtomicInteger(0);
@@ -329,7 +329,7 @@ public void run() {
                                     Thread.sleep(0, 100);
                                 }
                                 o.onCompleted();
-                            } catch (Exception e) {
+                            } catch (Throwable e) {
                                 o.onError(e);
                             } finally {
                                 finished.countDown();
diff --git a/rxjava-core/src/main/java/rx/operators/OperationOnErrorResumeNextViaFunction.java b/rxjava-core/src/main/java/rx/operators/OperationOnErrorResumeNextViaFunction.java
index c7ae0c3a3e..7110804dd9 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationOnErrorResumeNextViaFunction.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationOnErrorResumeNextViaFunction.java
@@ -53,16 +53,16 @@
  */
 public final class OperationOnErrorResumeNextViaFunction<T> {
 
-    public static <T> Func1<Observer<T>, Subscription> onErrorResumeNextViaFunction(Observable<T> originalSequence, Func1<Exception, Observable<T>> resumeFunction) {
+    public static <T> Func1<Observer<T>, Subscription> onErrorResumeNextViaFunction(Observable<T> originalSequence, Func1<Throwable, Observable<T>> resumeFunction) {
         return new OnErrorResumeNextViaFunction<T>(originalSequence, resumeFunction);
     }
 
     private static class OnErrorResumeNextViaFunction<T> implements Func1<Observer<T>, Subscription> {
 
-        private final Func1<Exception, Observable<T>> resumeFunction;
+        private final Func1<Throwable, Observable<T>> resumeFunction;
         private final Observable<T> originalSequence;
 
-        public OnErrorResumeNextViaFunction(Observable<T> originalSequence, Func1<Exception, Observable<T>> resumeFunction) {
+        public OnErrorResumeNextViaFunction(Observable<T> originalSequence, Func1<Throwable, Observable<T>> resumeFunction) {
             this.resumeFunction = resumeFunction;
             this.originalSequence = originalSequence;
         }
@@ -81,7 +81,7 @@ public void onNext(T value) {
                 /**
                  * Instead of passing the onError forward, we intercept and "resume" with the resumeSequence.
                  */
-                public void onError(Exception ex) {
+                public void onError(Throwable ex) {
                     /* remember what the current subscription is so we can determine if someone unsubscribes concurrently */
                     SafeObservableSubscription currentSubscription = subscriptionRef.get();
                     // check that we have not been unsubscribed before we can process the error
@@ -96,7 +96,7 @@ public void onError(Exception ex) {
                                 // so we want to immediately unsubscribe from the resumeSequence we just subscribed to
                                 innerSubscription.unsubscribe();
                             }
-                        } catch (Exception e) {
+                        } catch (Throwable e) {
                             // the resume function failed so we need to call onError
                             // I am using CompositeException so that both exceptions can be seen
                             observer.onError(new CompositeException("OnErrorResume function failed", Arrays.asList(ex, e)));
@@ -126,21 +126,21 @@ public static class UnitTest {
 
         @Test
         public void testResumeNextWithSynchronousExecution() {
-            final AtomicReference<Exception> receivedException = new AtomicReference<Exception>();
+            final AtomicReference<Throwable> receivedException = new AtomicReference<Throwable>();
             Observable<String> w = Observable.create(new Func1<Observer<String>, Subscription>() {
 
                 @Override
                 public Subscription call(Observer<String> observer) {
                     observer.onNext("one");
-                    observer.onError(new Exception("injected failure"));
+                    observer.onError(new Throwable("injected failure"));
                     return Subscriptions.empty();
                 }
             });
 
-            Func1<Exception, Observable<String>> resume = new Func1<Exception, Observable<String>>() {
+            Func1<Throwable, Observable<String>> resume = new Func1<Throwable, Observable<String>>() {
 
                 @Override
-                public Observable<String> call(Exception t1) {
+                public Observable<String> call(Throwable t1) {
                     receivedException.set(t1);
                     return Observable.from("twoResume", "threeResume");
                 }
@@ -152,7 +152,7 @@ public Observable<String> call(Exception t1) {
             Observer<String> aObserver = mock(Observer.class);
             observable.subscribe(aObserver);
 
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, Mockito.never()).onNext("two");
@@ -164,13 +164,13 @@ public Observable<String> call(Exception t1) {
 
         @Test
         public void testResumeNextWithAsyncExecution() {
-            final AtomicReference<Exception> receivedException = new AtomicReference<Exception>();
+            final AtomicReference<Throwable> receivedException = new AtomicReference<Throwable>();
             Subscription s = mock(Subscription.class);
             TestObservable w = new TestObservable(s, "one");
-            Func1<Exception, Observable<String>> resume = new Func1<Exception, Observable<String>>() {
+            Func1<Throwable, Observable<String>> resume = new Func1<Throwable, Observable<String>>() {
 
                 @Override
-                public Observable<String> call(Exception t1) {
+                public Observable<String> call(Throwable t1) {
                     receivedException.set(t1);
                     return Observable.from("twoResume", "threeResume");
                 }
@@ -188,7 +188,7 @@ public Observable<String> call(Exception t1) {
                 fail(e.getMessage());
             }
 
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, Mockito.never()).onNext("two");
@@ -205,10 +205,10 @@ public Observable<String> call(Exception t1) {
         public void testFunctionThrowsError() {
             Subscription s = mock(Subscription.class);
             TestObservable w = new TestObservable(s, "one");
-            Func1<Exception, Observable<String>> resume = new Func1<Exception, Observable<String>>() {
+            Func1<Throwable, Observable<String>> resume = new Func1<Throwable, Observable<String>>() {
 
                 @Override
-                public Observable<String> call(Exception t1) {
+                public Observable<String> call(Throwable t1) {
                     throw new RuntimeException("exception from function");
                 }
 
@@ -229,7 +229,7 @@ public Observable<String> call(Exception t1) {
             verify(aObserver, times(1)).onNext("one");
 
             // we should have received an onError call on the Observer since the resume function threw an exception
-            verify(aObserver, times(1)).onError(any(Exception.class));
+            verify(aObserver, times(1)).onError(any(Throwable.class));
             verify(aObserver, times(0)).onCompleted();
         }
 
@@ -258,7 +258,7 @@ public void run() {
                                 observer.onNext(s);
                             }
                             throw new RuntimeException("Forced Failure");
-                        } catch (Exception e) {
+                        } catch (Throwable e) {
                             observer.onError(e);
                         }
                     }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationOnErrorResumeNextViaObservable.java b/rxjava-core/src/main/java/rx/operators/OperationOnErrorResumeNextViaObservable.java
index e9e460e8f0..4ea879bdb9 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationOnErrorResumeNextViaObservable.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationOnErrorResumeNextViaObservable.java
@@ -81,7 +81,7 @@ public void onNext(T value) {
                 /**
                  * Instead of passing the onError forward, we intercept and "resume" with the resumeSequence.
                  */
-                public void onError(Exception ex) {
+                public void onError(Throwable ex) {
                     /* remember what the current subscription is so we can determine if someone unsubscribes concurrently */
                     SafeObservableSubscription currentSubscription = subscriptionRef.get();
                     // check that we have not been unsubscribed and not already resumed before we can process the error
@@ -136,7 +136,7 @@ public void testResumeNext() {
                 fail(e.getMessage());
             }
 
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, Mockito.never()).onNext("two");
@@ -176,7 +176,7 @@ public String call(String s) {
                 fail(e.getMessage());
             }
 
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, Mockito.never()).onNext("two");
@@ -213,7 +213,7 @@ public void run() {
                             }
                             System.out.println("TestObservable onCompleted");
                             observer.onCompleted();
-                        } catch (Exception e) {
+                        } catch (Throwable e) {
                             System.out.println("TestObservable onError: " + e);
                             observer.onError(e);
                         }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationOnErrorReturn.java b/rxjava-core/src/main/java/rx/operators/OperationOnErrorReturn.java
index ea1c9601bb..81a242ec25 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationOnErrorReturn.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationOnErrorReturn.java
@@ -50,15 +50,15 @@
  */
 public final class OperationOnErrorReturn<T> {
 
-    public static <T> Func1<Observer<T>, Subscription> onErrorReturn(Observable<T> originalSequence, Func1<Exception, T> resumeFunction) {
+    public static <T> Func1<Observer<T>, Subscription> onErrorReturn(Observable<T> originalSequence, Func1<Throwable, T> resumeFunction) {
         return new OnErrorReturn<T>(originalSequence, resumeFunction);
     }
 
     private static class OnErrorReturn<T> implements Func1<Observer<T>, Subscription> {
-        private final Func1<Exception, T> resumeFunction;
+        private final Func1<Throwable, T> resumeFunction;
         private final Observable<T> originalSequence;
 
-        public OnErrorReturn(Observable<T> originalSequence, Func1<Exception, T> resumeFunction) {
+        public OnErrorReturn(Observable<T> originalSequence, Func1<Throwable, T> resumeFunction) {
             this.resumeFunction = resumeFunction;
             this.originalSequence = originalSequence;
         }
@@ -79,7 +79,7 @@ public void onNext(T value) {
                 /**
                  * Instead of passing the onError forward, we intercept and "resume" with the resumeSequence.
                  */
-                public void onError(Exception ex) {
+                public void onError(Throwable ex) {
                     /* remember what the current subscription is so we can determine if someone unsubscribes concurrently */
                     SafeObservableSubscription currentSubscription = subscriptionRef.get();
                     // check that we have not been unsubscribed before we can process the error
@@ -99,7 +99,7 @@ public void onError(Exception ex) {
 
                             /* unsubscribe since it blew up */
                             currentSubscription.unsubscribe();
-                        } catch (Exception e) {
+                        } catch (Throwable e) {
                             // the return function failed so we need to call onError
                             // I am using CompositeException so that both exceptions can be seen
                             observer.onError(new CompositeException("OnErrorReturn function failed", Arrays.asList(ex, e)));
@@ -131,12 +131,12 @@ public static class UnitTest {
         public void testResumeNext() {
             Subscription s = mock(Subscription.class);
             TestObservable w = new TestObservable(s, "one");
-            final AtomicReference<Exception> capturedException = new AtomicReference<Exception>();
+            final AtomicReference<Throwable> capturedException = new AtomicReference<Throwable>();
 
-            Observable<String> observable = Observable.create(onErrorReturn(w, new Func1<Exception, String>() {
+            Observable<String> observable = Observable.create(onErrorReturn(w, new Func1<Throwable, String>() {
 
                 @Override
-                public String call(Exception e) {
+                public String call(Throwable e) {
                     capturedException.set(e);
                     return "failure";
                 }
@@ -153,7 +153,7 @@ public String call(Exception e) {
                 fail(e.getMessage());
             }
 
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, times(1)).onNext("failure");
@@ -167,12 +167,12 @@ public String call(Exception e) {
         public void testFunctionThrowsError() {
             Subscription s = mock(Subscription.class);
             TestObservable w = new TestObservable(s, "one");
-            final AtomicReference<Exception> capturedException = new AtomicReference<Exception>();
+            final AtomicReference<Throwable> capturedException = new AtomicReference<Throwable>();
 
-            Observable<String> observable = Observable.create(onErrorReturn(w, new Func1<Exception, String>() {
+            Observable<String> observable = Observable.create(onErrorReturn(w, new Func1<Throwable, String>() {
 
                 @Override
-                public String call(Exception e) {
+                public String call(Throwable e) {
                     capturedException.set(e);
                     throw new RuntimeException("exception from function");
                 }
@@ -193,7 +193,7 @@ public String call(Exception e) {
             verify(aObserver, times(1)).onNext("one");
 
             // we should have received an onError call on the Observer since the resume function threw an exception
-            verify(aObserver, times(1)).onError(any(Exception.class));
+            verify(aObserver, times(1)).onError(any(Throwable.class));
             verify(aObserver, times(0)).onCompleted();
             assertNotNull(capturedException.get());
         }
@@ -223,7 +223,7 @@ public void run() {
                                 observer.onNext(s);
                             }
                             throw new RuntimeException("Forced Failure");
-                        } catch (Exception e) {
+                        } catch (Throwable e) {
                             observer.onError(e);
                         }
                     }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationSample.java b/rxjava-core/src/main/java/rx/operators/OperationSample.java
index 74482c6bfb..b389fed150 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationSample.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationSample.java
@@ -83,7 +83,7 @@ public Subscription call(final Observer<T> observer) {
                 public void onCompleted() { /* the clock never completes */ }
                 
                 @Override
-                public void onError(Exception e) { /* the clock has no errors */ }
+                public void onError(Throwable e) { /* the clock has no errors */ }
                 
                 @Override
                 public void onNext(Long tick) {
@@ -101,7 +101,7 @@ public void onCompleted() {
                 }
         
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     clockSubscription.unsubscribe();
                     observer.onError(e);
                 }
@@ -170,31 +170,31 @@ public void call() {
             scheduler.advanceTimeTo(800L, TimeUnit.MILLISECONDS);
             verify(observer, never()).onNext(any(Long.class));
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
             
             scheduler.advanceTimeTo(1200L, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, times(1)).onNext(1L);
             verify(observer, never()).onNext(2L);
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(1600L, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, times(1)).onNext(1L);
             verify(observer, never()).onNext(2L);
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
             
             scheduler.advanceTimeTo(2000L, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, never()).onNext(1L);
             inOrder.verify(observer, times(1)).onNext(2L);
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
             
             scheduler.advanceTimeTo(3000L, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, never()).onNext(1L);
             inOrder.verify(observer, times(2)).onNext(2L);
             verify(observer, times(1)).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
         }
     }
 }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationScan.java b/rxjava-core/src/main/java/rx/operators/OperationScan.java
index 8a23f606de..24cb6ea66f 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationScan.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationScan.java
@@ -101,7 +101,7 @@ public synchronized void onNext(T value) {
                 }
                 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     observer.onError(e);
                 }
 
@@ -156,13 +156,13 @@ public synchronized void onNext(T value) {
             try {
                 acc = accumulatorFunction.call(acc, value);
                 observer.onNext(acc);
-            } catch (Exception ex) {
+            } catch (Throwable ex) {
                 observer.onError(ex);
             }
         }
         
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             observer.onError(e);
         }
         
@@ -196,14 +196,14 @@ public String call(String s, Integer n) {
             }));
             m.subscribe(observer);
 
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
             verify(observer, times(1)).onNext("");
             verify(observer, times(1)).onNext("1");
             verify(observer, times(1)).onNext("12");
             verify(observer, times(1)).onNext("123");
             verify(observer, times(4)).onNext(anyString());
             verify(observer, times(1)).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
         }
 
         @Test
@@ -223,14 +223,14 @@ public Integer call(Integer t1, Integer t2) {
             }));
             m.subscribe(Observer);
 
-            verify(Observer, never()).onError(any(Exception.class));
+            verify(Observer, never()).onError(any(Throwable.class));
             verify(Observer, never()).onNext(0);
             verify(Observer, times(1)).onNext(1);
             verify(Observer, times(1)).onNext(3);
             verify(Observer, times(1)).onNext(6);
             verify(Observer, times(3)).onNext(anyInt());
             verify(Observer, times(1)).onCompleted();
-            verify(Observer, never()).onError(any(Exception.class));
+            verify(Observer, never()).onError(any(Throwable.class));
         }
 
         @Test
@@ -250,12 +250,12 @@ public Integer call(Integer t1, Integer t2) {
             }));
             m.subscribe(Observer);
 
-            verify(Observer, never()).onError(any(Exception.class));
+            verify(Observer, never()).onError(any(Throwable.class));
             verify(Observer, never()).onNext(0);
             verify(Observer, times(1)).onNext(1);
             verify(Observer, times(1)).onNext(anyInt());
             verify(Observer, times(1)).onCompleted();
-            verify(Observer, never()).onError(any(Exception.class));
+            verify(Observer, never()).onError(any(Throwable.class));
         }
     }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationSkip.java b/rxjava-core/src/main/java/rx/operators/OperationSkip.java
index c3763e8d8a..c238b2d2ae 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationSkip.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationSkip.java
@@ -97,7 +97,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 observer.onError(e);
             }
 
@@ -126,7 +126,7 @@ public void testSkip1() {
             verify(aObserver, never()).onNext("one");
             verify(aObserver, never()).onNext("two");
             verify(aObserver, times(1)).onNext("three");
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -141,7 +141,7 @@ public void testSkip2() {
             verify(aObserver, never()).onNext("one");
             verify(aObserver, times(1)).onNext("two");
             verify(aObserver, times(1)).onNext("three");
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationSwitch.java b/rxjava-core/src/main/java/rx/operators/OperationSwitch.java
index 3e2e3fdfac..9de1b0be72 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationSwitch.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationSwitch.java
@@ -93,7 +93,7 @@ public void onCompleted() {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             unsubscribeFromSubSequence();
             observer.onError(e);
         }
@@ -109,7 +109,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     parent.unsubscribe();
                     observer.onError(e);
                 }
@@ -178,27 +178,27 @@ public Subscription call(Observer<String> observer) {
             scheduler.advanceTimeTo(90, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, never()).onNext(anyString());
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(125, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, times(1)).onNext("one");
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(175, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, times(1)).onNext("two");
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(225, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, times(1)).onNext("three");
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(350, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, never()).onNext(anyString());
             verify(observer, times(1)).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
         }
 
         @Test
@@ -238,22 +238,22 @@ public Subscription call(Observer<String> observer) {
             scheduler.advanceTimeTo(90, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, never()).onNext(anyString());
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(125, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, times(1)).onNext("one");
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(175, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, times(1)).onNext("two");
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(225, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, times(1)).onNext("three");
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(350, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, never()).onNext(anyString());
@@ -303,17 +303,17 @@ public Subscription call(Observer<String> observer) {
             scheduler.advanceTimeTo(90, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, never()).onNext(anyString());
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(125, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, times(1)).onNext("one");
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(250, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, times(1)).onNext("three");
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
         }
 
         @Test
@@ -358,12 +358,12 @@ public Subscription call(Observer<String> observer) {
             scheduler.advanceTimeTo(90, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, never()).onNext(anyString());
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(125, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, times(1)).onNext("one");
             verify(observer, never()).onCompleted();
-            verify(observer, never()).onError(any(Exception.class));
+            verify(observer, never()).onError(any(Throwable.class));
 
             scheduler.advanceTimeTo(250, TimeUnit.MILLISECONDS);
             inOrder.verify(observer, never()).onNext("three");
@@ -380,7 +380,7 @@ public void call() {
             }, delay, TimeUnit.MILLISECONDS);
         }
 
-        private <T> void publishError(final Observer<T> observer, long delay, final Exception error) {
+        private <T> void publishError(final Observer<T> observer, long delay, final Throwable error) {
             scheduler.schedule(new Action0() {
                 @Override
                 public void call() {
@@ -399,7 +399,7 @@ public void call() {
         }
 
         @SuppressWarnings("serial")
-        private class TestException extends Exception {
+        private class TestException extends Throwable {
         }
     }
 }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationSynchronize.java b/rxjava-core/src/main/java/rx/operators/OperationSynchronize.java
index b6998eaa1d..b182063038 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationSynchronize.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationSynchronize.java
@@ -137,7 +137,7 @@ public void testOnErrorAfterUnSubscribe() {
             t.sendOnError(new RuntimeException("bad"));
 
             verify(w, times(1)).onNext("one");
-            verify(w, Mockito.never()).onError(any(Exception.class));
+            verify(w, Mockito.never()).onError(any(Throwable.class));
         }
 
         /**
@@ -158,7 +158,7 @@ public void testOnNextAfterOnError() {
             t.sendOnNext("two");
 
             verify(w, times(1)).onNext("one");
-            verify(w, times(1)).onError(any(Exception.class));
+            verify(w, times(1)).onError(any(Throwable.class));
             verify(w, Mockito.never()).onNext("two");
         }
 
@@ -180,7 +180,7 @@ public void testOnCompletedAfterOnError() {
             t.sendOnCompleted();
 
             verify(w, times(1)).onNext("one");
-            verify(w, times(1)).onError(any(Exception.class));
+            verify(w, times(1)).onError(any(Throwable.class));
             verify(w, Mockito.never()).onCompleted();
         }
 
@@ -204,7 +204,7 @@ public void testOnNextAfterOnCompleted() {
             verify(w, times(1)).onNext("one");
             verify(w, Mockito.never()).onNext("two");
             verify(w, times(1)).onCompleted();
-            verify(w, Mockito.never()).onError(any(Exception.class));
+            verify(w, Mockito.never()).onError(any(Throwable.class));
         }
 
         /**
@@ -226,7 +226,7 @@ public void testOnErrorAfterOnCompleted() {
 
             verify(w, times(1)).onNext("one");
             verify(w, times(1)).onCompleted();
-            verify(w, Mockito.never()).onError(any(Exception.class));
+            verify(w, Mockito.never()).onError(any(Throwable.class));
         }
 
         /**
@@ -250,7 +250,7 @@ public void sendOnNext(String value) {
             }
 
             /* used to simulate subscription */
-            public void sendOnError(Exception e) {
+            public void sendOnError(Throwable e) {
                 observer.onError(e);
             }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationTake.java b/rxjava-core/src/main/java/rx/operators/OperationTake.java
index baefcbf8f3..c88001f1d1 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationTake.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationTake.java
@@ -95,7 +95,7 @@ public void onCompleted()
                     }
 
                     @Override
-                    public void onError(Exception e)
+                    public void onError(Throwable e)
                     {
                     }
 
@@ -128,7 +128,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 if (counter.getAndSet(num) < num) {
                     observer.onError(e);
                 }
@@ -166,7 +166,7 @@ public void testTake1() {
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, times(1)).onNext("two");
             verify(aObserver, never()).onNext("three");
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -181,7 +181,7 @@ public void testTake2() {
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, never()).onNext("two");
             verify(aObserver, never()).onNext("three");
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -193,7 +193,7 @@ public void testTakeDoesntLeakErrors() {
                 public Subscription call(Observer<String> observer)
                 {
                     observer.onNext("one");
-                    observer.onError(new Exception("test failed"));
+                    observer.onError(new Throwable("test failed"));
                     return Subscriptions.empty();
                 }
             });
@@ -220,7 +220,7 @@ public void testTakeZeroDoesntLeakError() {
                 public Subscription call(Observer<String> observer)
                 {
                     subscribed.set(true);
-                    observer.onError(new Exception("test failed"));
+                    observer.onError(new Throwable("test failed"));
                     return new Subscription()
                     {
                         @Override
@@ -259,7 +259,7 @@ public void testUnsubscribeAfterTake() {
             // wait for the Observable to complete
             try {
                 w.t.join();
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 e.printStackTrace();
                 fail(e.getMessage());
             }
@@ -298,7 +298,7 @@ public void run() {
                                 observer.onNext(s);
                             }
                             observer.onCompleted();
-                        } catch (Exception e) {
+                        } catch (Throwable e) {
                             throw new RuntimeException(e);
                         }
                     }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationTakeLast.java b/rxjava-core/src/main/java/rx/operators/OperationTakeLast.java
index 569d4cc603..2abe8381b7 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationTakeLast.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationTakeLast.java
@@ -81,7 +81,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 observer.onError(e);
             }
 
@@ -107,7 +107,7 @@ public void testTakeLastEmpty() {
             Observer<String> aObserver = mock(Observer.class);
             take.subscribe(aObserver);
             verify(aObserver, never()).onNext(any(String.class));
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -123,7 +123,7 @@ public void testTakeLast1() {
             inOrder.verify(aObserver, times(1)).onNext("two");
             inOrder.verify(aObserver, times(1)).onNext("three");
             verify(aObserver, never()).onNext("one");
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -136,7 +136,7 @@ public void testTakeLast2() {
             Observer<String> aObserver = mock(Observer.class);
             take.subscribe(aObserver);
             verify(aObserver, times(1)).onNext("one");
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationTakeUntil.java b/rxjava-core/src/main/java/rx/operators/OperationTakeUntil.java
index 6c5ba77510..fb33a08642 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationTakeUntil.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationTakeUntil.java
@@ -105,7 +105,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     notificationObserver.onError(e);
                 }
 
@@ -133,7 +133,7 @@ public void onCompleted() {
                 }
 
                 @Override
-                public void onError(Exception e) {
+                public void onError(Throwable e) {
                     notificationObserver.onError(e);
                 }
 
@@ -203,7 +203,7 @@ public void testTakeUntilSourceError() {
             Subscription sOther = mock(Subscription.class);
             TestObservable source = new TestObservable(sSource);
             TestObservable other = new TestObservable(sOther);
-            Exception error = new Exception();
+            Throwable error = new Throwable();
 
             Observer<String> result = mock(Observer.class);
             Observable<String> stringObservable = takeUntil(source, other);
@@ -227,7 +227,7 @@ public void testTakeUntilOtherError() {
             Subscription sOther = mock(Subscription.class);
             TestObservable source = new TestObservable(sSource);
             TestObservable other = new TestObservable(sOther);
-            Exception error = new Exception();
+            Throwable error = new Throwable();
 
             Observer<String> result = mock(Observer.class);
             Observable<String> stringObservable = takeUntil(source, other);
@@ -288,7 +288,7 @@ public void sendOnNext(String value) {
             }
 
             /* used to simulate subscription */
-            public void sendOnError(Exception e) {
+            public void sendOnError(Throwable e) {
                 observer.onError(e);
             }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationTakeWhile.java b/rxjava-core/src/main/java/rx/operators/OperationTakeWhile.java
index 273e6cac67..12038e72b0 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationTakeWhile.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationTakeWhile.java
@@ -125,7 +125,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 observer.onError(e);
             }
 
@@ -134,7 +134,7 @@ public void onNext(T args) {
                 Boolean isSelected;
                 try {
                     isSelected = predicate.call(args, counter.getAndIncrement());
-                } catch (Exception e) {
+                } catch (Throwable e) {
                     observer.onError(e);
                     return;
                 }
@@ -171,7 +171,7 @@ public Boolean call(Integer input)
             verify(aObserver, times(1)).onNext(1);
             verify(aObserver, times(1)).onNext(2);
             verify(aObserver, never()).onNext(3);
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -203,7 +203,7 @@ public Boolean call(Integer input)
             verify(aObserver, never()).onNext(3);
             verify(aObserver, never()).onNext(4);
             verify(aObserver, never()).onNext(5);
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -225,7 +225,7 @@ public Boolean call(String input, Integer index)
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, times(1)).onNext("two");
             verify(aObserver, never()).onNext("three");
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -237,7 +237,7 @@ public void testTakeWhileDoesntLeakErrors() {
                 public Subscription call(Observer<String> observer)
                 {
                     observer.onNext("one");
-                    observer.onError(new Exception("test failed"));
+                    observer.onError(new Throwable("test failed"));
                     return Subscriptions.empty();
                 }
             });
@@ -272,7 +272,7 @@ public Boolean call(String s)
             // wait for the Observable to complete
             try {
                 source.t.join();
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 e.printStackTrace();
                 fail(e.getMessage());
             }
@@ -301,7 +301,7 @@ public Boolean call(String s, Integer index)
             // wait for the Observable to complete
             try {
                 w.t.join();
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 e.printStackTrace();
                 fail(e.getMessage());
             }
@@ -338,7 +338,7 @@ public void run() {
                                 observer.onNext(s);
                             }
                             observer.onCompleted();
-                        } catch (Exception e) {
+                        } catch (Throwable e) {
                             throw new RuntimeException(e);
                         }
                     }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationToFuture.java b/rxjava-core/src/main/java/rx/operators/OperationToFuture.java
index 6a024a0d6d..5f9b86d7cf 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationToFuture.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationToFuture.java
@@ -41,7 +41,7 @@ public static <T> Future<T> toFuture(Observable<T> that) {
 
         final CountDownLatch finished = new CountDownLatch(1);
         final AtomicReference<T> value = new AtomicReference<T>();
-        final AtomicReference<Exception> error = new AtomicReference<Exception>();
+        final AtomicReference<Throwable> error = new AtomicReference<Throwable>();
 
         final Subscription s = that.subscribe(new Observer<T>() {
 
@@ -51,7 +51,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 error.compareAndSet(null, e);
                 finished.countDown();
             }
@@ -161,7 +161,7 @@ public Subscription call(Observer<String> observer) {
         try {
             f.get();
             fail("expected exception");
-        } catch (Exception e) {
+        } catch (Throwable e) {
             assertEquals(TestException.class, e.getCause().getClass());
         }
     }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationToIterator.java b/rxjava-core/src/main/java/rx/operators/OperationToIterator.java
index a5817ac236..f3c1b21067 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationToIterator.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationToIterator.java
@@ -59,7 +59,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 // ignore
             }
 
@@ -86,7 +86,7 @@ public T next() {
                     buf = take();
                 }
                 if (buf.isOnError()) {
-                    throw Exceptions.propagate(buf.getException());
+                    throw Exceptions.propagate(buf.getThrowable());
                 }
 
                 T result = buf.getValue();
diff --git a/rxjava-core/src/main/java/rx/operators/OperationToObservableFuture.java b/rxjava-core/src/main/java/rx/operators/OperationToObservableFuture.java
index ae40d78103..e7ee406cea 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationToObservableFuture.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationToObservableFuture.java
@@ -50,7 +50,7 @@ public Subscription call(Observer<T> observer) {
                     observer.onNext(value);
                 }
                 observer.onCompleted();
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 observer.onError(e);
             }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationToObservableIterable.java b/rxjava-core/src/main/java/rx/operators/OperationToObservableIterable.java
index d4179fde33..0976f9113c 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationToObservableIterable.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationToObservableIterable.java
@@ -72,7 +72,7 @@ public void testIterable() {
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, times(1)).onNext("two");
             verify(aObserver, times(1)).onNext("three");
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
     }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationToObservableList.java b/rxjava-core/src/main/java/rx/operators/OperationToObservableList.java
index 49cbc5d943..7258938d11 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationToObservableList.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationToObservableList.java
@@ -68,7 +68,7 @@ public void onNext(T value) {
                     list.add(value);
                 }
 
-                public void onError(Exception ex) {
+                public void onError(Throwable ex) {
                     observer.onError(ex);
                 }
 
@@ -85,7 +85,7 @@ public void onCompleted() {
                         // observer.onNext(Collections.unmodifiableList(l));
                         observer.onNext(l);
                         observer.onCompleted();
-                    } catch (Exception e) {
+                    } catch (Throwable e) {
                         onError(e);
                     }
 
@@ -105,7 +105,7 @@ public void testList() {
             Observer<List<String>> aObserver = mock(Observer.class);
             observable.subscribe(aObserver);
             verify(aObserver, times(1)).onNext(Arrays.asList("one", "two", "three"));
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -125,11 +125,11 @@ public void testListMultipleObservers() {
             List<String> expected = Arrays.asList("one", "two", "three");
 
             verify(o1, times(1)).onNext(expected);
-            verify(o1, Mockito.never()).onError(any(Exception.class));
+            verify(o1, Mockito.never()).onError(any(Throwable.class));
             verify(o1, times(1)).onCompleted();
 
             verify(o2, times(1)).onNext(expected);
-            verify(o2, Mockito.never()).onError(any(Exception.class));
+            verify(o2, Mockito.never()).onError(any(Throwable.class));
             verify(o2, times(1)).onCompleted();
         }
     }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationToObservableSortedList.java b/rxjava-core/src/main/java/rx/operators/OperationToObservableSortedList.java
index 831ddd9725..536def4cd2 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationToObservableSortedList.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationToObservableSortedList.java
@@ -92,7 +92,7 @@ public void onNext(T value) {
                     list.add(value);
                 }
 
-                public void onError(Exception ex) {
+                public void onError(Throwable ex) {
                     observer.onError(ex);
                 }
 
@@ -116,7 +116,7 @@ public int compare(T o1, T o2) {
 
                         observer.onNext(Collections.unmodifiableList(l));
                         observer.onCompleted();
-                    } catch (Exception e) {
+                    } catch (Throwable e) {
                         onError(e);
                     }
 
@@ -154,7 +154,7 @@ public void testSortedList() {
             Observer<List<Integer>> aObserver = mock(Observer.class);
             observable.subscribe(aObserver);
             verify(aObserver, times(1)).onNext(Arrays.asList(1, 2, 3, 4, 5));
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -174,7 +174,7 @@ public Integer call(Integer t1, Integer t2) {
             Observer<List<Integer>> aObserver = mock(Observer.class);
             observable.subscribe(aObserver);
             verify(aObserver, times(1)).onNext(Arrays.asList(5, 4, 3, 2, 1));
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
diff --git a/rxjava-core/src/main/java/rx/operators/OperationWhere.java b/rxjava-core/src/main/java/rx/operators/OperationWhere.java
index e667e86d46..d82b6d829b 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationWhere.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationWhere.java
@@ -58,7 +58,7 @@ public Boolean call(String t1) {
             verify(aObserver, Mockito.never()).onNext("one");
             verify(aObserver, times(1)).onNext("two");
             verify(aObserver, Mockito.never()).onNext("three");
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
     }
diff --git a/rxjava-core/src/main/java/rx/operators/OperationZip.java b/rxjava-core/src/main/java/rx/operators/OperationZip.java
index a8989d4d90..92d987ffa7 100644
--- a/rxjava-core/src/main/java/rx/operators/OperationZip.java
+++ b/rxjava-core/src/main/java/rx/operators/OperationZip.java
@@ -115,7 +115,7 @@ public void onCompleted() {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             a.error(this, e);
         }
 
@@ -123,7 +123,7 @@ public void onError(Exception e) {
         public void onNext(T args) {
             try {
                 a.next(this, args);
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 onError(e);
             }
         }
@@ -189,7 +189,7 @@ void complete(ZipObserver<T, ?> w) {
          * 
          * @param w
          */
-        void error(ZipObserver<T, ?> w, Exception e) {
+        void error(ZipObserver<T, ?> w, Throwable e) {
             if (running.compareAndSet(true, false)) {
                 // this thread succeeded in setting running=false so let's propagate the error
                 observer.onError(e);
@@ -308,7 +308,7 @@ public void testCollectionSizeDifferentThanFunction() {
             Observable<String> w = Observable.create(zip(ws, zipr));
             w.subscribe(aObserver);
 
-            verify(aObserver, times(1)).onError(any(Exception.class));
+            verify(aObserver, times(1)).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             verify(aObserver, never()).onNext(any(String.class));
         }
@@ -412,14 +412,14 @@ public void testAggregatorSimple() {
 
             InOrder inOrder = inOrder(aObserver);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             inOrder.verify(aObserver, times(1)).onNext("helloworld");
 
             a.next(r1, "hello ");
             a.next(r2, "again");
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             inOrder.verify(aObserver, times(1)).onNext("hello again");
 
@@ -457,14 +457,14 @@ public void testAggregatorDifferentSizedResultsWithOnComplete() {
 
             InOrder inOrder = inOrder(aObserver);
 
-            inOrder.verify(aObserver, never()).onError(any(Exception.class));
+            inOrder.verify(aObserver, never()).onError(any(Throwable.class));
             inOrder.verify(aObserver, never()).onCompleted();
             inOrder.verify(aObserver, times(1)).onNext("helloworld");
 
             a.next(r1, "hi");
             a.complete(r1);
 
-            inOrder.verify(aObserver, never()).onError(any(Exception.class));
+            inOrder.verify(aObserver, never()).onError(any(Throwable.class));
             inOrder.verify(aObserver, times(1)).onCompleted();
             inOrder.verify(aObserver, never()).onNext(anyString());
         }
@@ -496,14 +496,14 @@ public void testAggregateMultipleTypes() {
 
             InOrder inOrder = inOrder(aObserver);
 
-            inOrder.verify(aObserver, never()).onError(any(Exception.class));
+            inOrder.verify(aObserver, never()).onError(any(Throwable.class));
             inOrder.verify(aObserver, never()).onCompleted();
             inOrder.verify(aObserver, times(1)).onNext("helloworld");
 
             a.next(r1, "hi");
             a.complete(r1);
 
-            inOrder.verify(aObserver, never()).onError(any(Exception.class));
+            inOrder.verify(aObserver, never()).onError(any(Throwable.class));
             inOrder.verify(aObserver, times(1)).onCompleted();
             inOrder.verify(aObserver, never()).onNext(anyString());
         }
@@ -535,7 +535,7 @@ public void testAggregate3Types() {
             a.next(r2, 2);
             a.next(r3, new int[] { 5, 6, 7 });
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             verify(aObserver, times(1)).onNext("hello2[5, 6, 7]");
         }
@@ -566,7 +566,7 @@ public void testAggregatorsWithDifferentSizesAndTiming() {
             a.next(r1, "three");
             a.next(r2, "A");
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             verify(aObserver, times(1)).onNext("oneA");
 
@@ -582,7 +582,7 @@ public void testAggregatorsWithDifferentSizesAndTiming() {
             verify(aObserver, never()).onNext("E");
             a.complete(r2);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -610,7 +610,7 @@ public void testAggregatorError() {
             a.next(r1, "hello");
             a.next(r2, "world");
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             verify(aObserver, times(1)).onNext("helloworld");
 
@@ -618,7 +618,7 @@ public void testAggregatorError() {
             a.next(r1, "hello");
             a.next(r2, "again");
 
-            verify(aObserver, times(1)).onError(any(Exception.class));
+            verify(aObserver, times(1)).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             // we don't want to be called again after an error
             verify(aObserver, times(0)).onNext("helloagain");
@@ -648,7 +648,7 @@ public void testAggregatorUnsubscribe() {
             a.next(r1, "hello");
             a.next(r2, "world");
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             verify(aObserver, times(1)).onNext("helloworld");
 
@@ -656,7 +656,7 @@ public void testAggregatorUnsubscribe() {
             a.next(r1, "hello");
             a.next(r2, "again");
 
-            verify(aObserver, times(0)).onError(any(Exception.class));
+            verify(aObserver, times(0)).onError(any(Throwable.class));
             verify(aObserver, never()).onCompleted();
             // we don't want to be called again after an error
             verify(aObserver, times(0)).onNext("helloagain");
@@ -690,13 +690,13 @@ public void testAggregatorEarlyCompletion() {
 
             InOrder inOrder = inOrder(aObserver);
 
-            inOrder.verify(aObserver, never()).onError(any(Exception.class));
+            inOrder.verify(aObserver, never()).onError(any(Throwable.class));
             inOrder.verify(aObserver, never()).onCompleted();
             inOrder.verify(aObserver, times(1)).onNext("oneA");
 
             a.complete(r2);
 
-            inOrder.verify(aObserver, never()).onError(any(Exception.class));
+            inOrder.verify(aObserver, never()).onError(any(Throwable.class));
             inOrder.verify(aObserver, times(1)).onCompleted();
             inOrder.verify(aObserver, never()).onNext(anyString());
         }
@@ -713,7 +713,7 @@ public void testZip2Types() {
             Observable<String> w = Observable.create(zip(Observable.from("one", "two"), Observable.from(2, 3, 4), zipr));
             w.subscribe(aObserver);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("one2");
             verify(aObserver, times(1)).onNext("two3");
@@ -732,7 +732,7 @@ public void testZip3Types() {
             Observable<String> w = Observable.create(zip(Observable.from("one", "two"), Observable.from(2), Observable.from(new int[] { 4, 5, 6 }), zipr));
             w.subscribe(aObserver);
 
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             verify(aObserver, times(1)).onNext("one2[4, 5, 6]");
             verify(aObserver, never()).onNext("two");
@@ -748,7 +748,7 @@ public void testOnNextExceptionInvokesOnError() {
             Observable<Integer> w = Observable.create(zip(Observable.from(10, 20, 30), Observable.from(0, 1, 2), zipr));
             w.subscribe(aObserver);
 
-            verify(aObserver, times(1)).onError(any(Exception.class));
+            verify(aObserver, times(1)).onError(any(Throwable.class));
         }
 
         private Func2<Integer, Integer, Integer> getDivideZipr() {
diff --git a/rxjava-core/src/main/java/rx/operators/SafeObserver.java b/rxjava-core/src/main/java/rx/operators/SafeObserver.java
index 2d6055a213..f9a2553d4d 100644
--- a/rxjava-core/src/main/java/rx/operators/SafeObserver.java
+++ b/rxjava-core/src/main/java/rx/operators/SafeObserver.java
@@ -56,7 +56,7 @@ public void onCompleted() {
         if (isFinished.compareAndSet(false, true)) {
             try {
                 actual.onCompleted();
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 // handle errors if the onCompleted implementation fails, not just if the Observable fails
                 onError(e);
             }
@@ -66,11 +66,11 @@ public void onCompleted() {
     }
 
     @Override
-    public void onError(Exception e) {
+    public void onError(Throwable e) {
         if (isFinished.compareAndSet(false, true)) {
             try {
                 actual.onError(e);
-            } catch (Exception e2) {
+            } catch (Throwable e2) {
                 if (e2 instanceof OnErrorNotImplementedException) {
                     /**
                      * onError isn't implemented so throw
@@ -105,7 +105,7 @@ public void onNext(T args) {
             if (!isFinished.get()) {
                 actual.onNext(args);
             }
-        } catch (Exception e) {
+        } catch (Throwable e) {
             // handle errors if the onNext implementation fails, not just if the Observable fails
             onError(e);
         }
diff --git a/rxjava-core/src/main/java/rx/operators/ScheduledObserver.java b/rxjava-core/src/main/java/rx/operators/ScheduledObserver.java
index 86c1fecb2e..205dfb0ca7 100644
--- a/rxjava-core/src/main/java/rx/operators/ScheduledObserver.java
+++ b/rxjava-core/src/main/java/rx/operators/ScheduledObserver.java
@@ -41,7 +41,7 @@ public void onCompleted() {
     }
 
     @Override
-    public void onError(final Exception e) {
+    public void onError(final Throwable e) {
         enqueue(new Notification<T>(e));
     }
 
@@ -73,7 +73,7 @@ public void call() {
                     underlying.onNext(not.getValue());
                     break;
                 case OnError:
-                    underlying.onError(not.getException());
+                    underlying.onError(not.getThrowable());
                     break;
                 case OnCompleted:
                     underlying.onCompleted();
diff --git a/rxjava-core/src/main/java/rx/operators/SynchronizedObserver.java b/rxjava-core/src/main/java/rx/operators/SynchronizedObserver.java
index b03073acb9..37b36f2c27 100644
--- a/rxjava-core/src/main/java/rx/operators/SynchronizedObserver.java
+++ b/rxjava-core/src/main/java/rx/operators/SynchronizedObserver.java
@@ -89,7 +89,7 @@ public void onNext(T arg) {
         }
     }
 
-    public void onError(Exception e) {
+    public void onError(Throwable e) {
         if (finished || subscription.isUnsubscribed()) {
             // another thread has already finished us, so we won't proceed
             return;
@@ -145,7 +145,7 @@ public void testSingleThreadedBasic() {
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, times(1)).onNext("two");
             verify(aObserver, times(1)).onNext("three");
-            verify(aObserver, never()).onError(any(Exception.class));
+            verify(aObserver, never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
             // non-deterministic because unsubscribe happens after 'waitToFinish' releases
             // so commenting out for now as this is not a critical thing to test here
@@ -284,7 +284,7 @@ public void runConcurrencyTest() {
                 @SuppressWarnings("unused")
                 int numNextEvents = tw.assertEvents(null); // no check of type since we don't want to test barging results here, just interleaving behavior
                 // System.out.println("Number of events executed: " + numNextEvents);
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 fail("Concurrency test failed: " + e.getMessage());
                 e.printStackTrace();
             } finally {
@@ -301,7 +301,7 @@ private static void waitOnThreads(Future<?>... futures) {
             for (Future<?> f : futures) {
                 try {
                     f.get(10, TimeUnit.SECONDS);
-                } catch (Exception e) {
+                } catch (Throwable e) {
                     System.err.println("Failed while waiting on future.");
                     e.printStackTrace();
                 }
@@ -351,7 +351,7 @@ public void run() {
                     for (Future<?> f : waitOnThese) {
                         try {
                             f.get();
-                        } catch (Exception e) {
+                        } catch (Throwable e) {
                             System.err.println("Error while waiting on future in CompletionThread");
                         }
                     }
@@ -394,7 +394,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 events.add(TestConcurrencyObserverEvent.onError);
             }
 
@@ -489,7 +489,7 @@ public void run() {
                                 observer.onNext(s);
                             }
                             observer.onCompleted();
-                        } catch (Exception e) {
+                        } catch (Throwable e) {
                             throw new RuntimeException(e);
                         }
                     }
@@ -559,7 +559,7 @@ public void run() {
                                             if (concurrentThreads > maxThreads) {
                                                 maxConcurrentThreads.compareAndSet(maxThreads, concurrentThreads);
                                             }
-                                        } catch (Exception e) {
+                                        } catch (Throwable e) {
                                             observer.onError(e);
                                         } finally {
                                             threadsRunning.decrementAndGet();
@@ -569,7 +569,7 @@ public void run() {
                             }
                             // we are done spawning threads
                             threadPool.shutdown();
-                        } catch (Exception e) {
+                        } catch (Throwable e) {
                             throw new RuntimeException(e);
                         }
 
@@ -612,7 +612,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 System.out.println(">>> BusyObserver received onError: " + e.getMessage());
                 onError = true;
             }
diff --git a/rxjava-core/src/main/java/rx/plugins/RxJavaErrorHandler.java b/rxjava-core/src/main/java/rx/plugins/RxJavaErrorHandler.java
index 042d59a8ab..8b621bb651 100644
--- a/rxjava-core/src/main/java/rx/plugins/RxJavaErrorHandler.java
+++ b/rxjava-core/src/main/java/rx/plugins/RxJavaErrorHandler.java
@@ -19,9 +19,9 @@
 import rx.Observer;
 
 /**
- * Abstract class for defining error handling logic in addition to the normal {@link Observer#onError(Exception)} behavior.
+ * Abstract class for defining error handling logic in addition to the normal {@link Observer#onError(Throwable)} behavior.
  * <p>
- * For example, all Exceptions can be logged using this handler even if {@link Observer#onError(Exception)} is ignored or not provided when an {@link Observable} is subscribed to.
+ * For example, all Exceptions can be logged using this handler even if {@link Observer#onError(Throwable)} is ignored or not provided when an {@link Observable} is subscribed to.
  * <p>
  * See {@link RxJavaPlugins} or the RxJava GitHub Wiki for information on configuring plugins: <a
  * href="https://github.com/Netflix/RxJava/wiki/Plugins">https://github.com/Netflix/RxJava/wiki/Plugins</a>.
@@ -29,12 +29,12 @@
 public abstract class RxJavaErrorHandler {
 
     /**
-     * Receives all Exceptions from an {@link Observable} passed to {@link Observer#onError(Exception)}.
+     * Receives all Exceptions from an {@link Observable} passed to {@link Observer#onError(Throwable)}.
      * 
      * @param e
      *            Exception
      */
-    public void handleError(Exception e) {
+    public void handleError(Throwable e) {
         // do nothing by default
     }
 
diff --git a/rxjava-core/src/main/java/rx/plugins/RxJavaObservableExecutionHook.java b/rxjava-core/src/main/java/rx/plugins/RxJavaObservableExecutionHook.java
index eac11fa79f..2aba6edecd 100644
--- a/rxjava-core/src/main/java/rx/plugins/RxJavaObservableExecutionHook.java
+++ b/rxjava-core/src/main/java/rx/plugins/RxJavaObservableExecutionHook.java
@@ -69,18 +69,18 @@ public <T> Subscription onSubscribeReturn(Observable<T> observableInstance, Subs
     }
 
     /**
-     * Invoked after failed execution of {@link Observable#subscribe(Observer)} with thrown Exception.
+     * Invoked after failed execution of {@link Observable#subscribe(Observer)} with thrown Throwable.
      * <p>
-     * This is NOT errors emitted via {@link Observer#onError(Exception)} but exceptions thrown when attempting
+     * This is NOT errors emitted via {@link Observer#onError(Throwable)} but exceptions thrown when attempting
      * to subscribe to a {@link Func1}<{@link Observer}{@code <T>}, {@link Subscription}>.
      * 
      * @param observableInstance
      *            The executing {@link Observable} instance.
      * @param e
-     *            Exception thrown by {@link Observable#subscribe(Observer)}
-     * @return Exception that can be decorated, replaced or just returned as a pass-thru.
+     *            Throwable thrown by {@link Observable#subscribe(Observer)}
+     * @return Throwable that can be decorated, replaced or just returned as a pass-thru.
      */
-    public <T> Exception onSubscribeError(Observable<T> observableInstance, Exception e) {
+    public <T> Throwable onSubscribeError(Observable<T> observableInstance, Throwable e) {
         // pass-thru by default
         return e;
     }
diff --git a/rxjava-core/src/main/java/rx/subjects/AsyncSubject.java b/rxjava-core/src/main/java/rx/subjects/AsyncSubject.java
index f4978831c2..b154702ff8 100644
--- a/rxjava-core/src/main/java/rx/subjects/AsyncSubject.java
+++ b/rxjava-core/src/main/java/rx/subjects/AsyncSubject.java
@@ -113,7 +113,7 @@ public void onCompleted() {
     }
 
     @Override
-    public void onError(Exception e) {
+    public void onError(Throwable e) {
         for (Observer<T> observer : observers.values()) {
             observer.onError(e);
         }
@@ -126,7 +126,7 @@ public void onNext(T args) {
 
     public static class UnitTest {
 
-        private final Exception testException = new Exception();
+        private final Throwable testException = new Throwable();
 
         @Test
         public void testNeverCompleted() {
@@ -169,7 +169,7 @@ public void testCompleted() {
         private void assertCompletedObserver(Observer<String> aObserver)
         {
             verify(aObserver, times(1)).onNext("three");
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -186,7 +186,7 @@ public void testError() {
             subject.onNext("three");
             subject.onError(testException);
             subject.onNext("four");
-            subject.onError(new Exception());
+            subject.onError(new Throwable());
             subject.onCompleted();
 
             assertErrorObserver(aObserver);
@@ -222,7 +222,7 @@ public void testUnsubscribeBeforeCompleted() {
         private void assertNoOnNextEventsReceived(Observer<String> aObserver)
         {
             verify(aObserver, Mockito.never()).onNext(anyString());
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, Mockito.never()).onCompleted();
         }
 
@@ -248,7 +248,7 @@ public void call(AsyncSubject<Object> DefaultSubject)
                 @Override
                 public void call(AsyncSubject<Object> DefaultSubject)
                 {
-                    DefaultSubject.onError(new Exception());
+                    DefaultSubject.onError(new Throwable());
                 }
             },
             null);
diff --git a/rxjava-core/src/main/java/rx/subjects/BehaviorSubject.java b/rxjava-core/src/main/java/rx/subjects/BehaviorSubject.java
index a7c369e557..bed456b5ba 100644
--- a/rxjava-core/src/main/java/rx/subjects/BehaviorSubject.java
+++ b/rxjava-core/src/main/java/rx/subjects/BehaviorSubject.java
@@ -115,7 +115,7 @@ public void onCompleted() {
     }
 
     @Override
-    public void onError(Exception e) {
+    public void onError(Throwable e) {
         for (Observer<T> observer : observers.values()) {
             observer.onError(e);
         }
@@ -131,7 +131,7 @@ public void onNext(T args) {
 
     public static class UnitTest {
 
-        private final Exception testException = new Exception();
+        private final Throwable testException = new Throwable();
 
         @Test
         public void testThatObserverReceivesDefaultValueIfNothingWasPublished() {
@@ -200,7 +200,7 @@ private void assertCompletedObserver(Observer<String> aObserver)
         {
             verify(aObserver, times(1)).onNext("default");
             verify(aObserver, times(1)).onNext("one");
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -249,7 +249,7 @@ public void call(BehaviorSubject<String> DefaultSubject)
                 @Override
                 public void call(BehaviorSubject<String> DefaultSubject)
                 {
-                    DefaultSubject.onError(new Exception());
+                    DefaultSubject.onError(new Throwable());
                 }
             }, new Action1<BehaviorSubject<String>>()
             {
diff --git a/rxjava-core/src/main/java/rx/subjects/PublishSubject.java b/rxjava-core/src/main/java/rx/subjects/PublishSubject.java
index 003d839f50..5fccdb86d2 100644
--- a/rxjava-core/src/main/java/rx/subjects/PublishSubject.java
+++ b/rxjava-core/src/main/java/rx/subjects/PublishSubject.java
@@ -117,7 +117,7 @@ private Subscription checkTerminalState(Observer<T> observer) {
                     if (n.isOnCompleted()) {
                         observer.onCompleted();
                     } else {
-                        observer.onError(n.getException());
+                        observer.onError(n.getThrowable());
                     }
                     return Subscriptions.empty();
                 } else {
@@ -155,7 +155,7 @@ public void onCompleted() {
     }
 
     @Override
-    public void onError(Exception e) {
+    public void onError(Throwable e) {
         /**
          * Synchronizing despite terminalState being an AtomicReference because of multi-step logic in subscription.
          * Why use AtomicReference then? Convenient for passing around a mutable reference holder between the
@@ -241,7 +241,7 @@ public void unsubscribe() {
             sub.unsubscribe();
         }
 
-        private final Exception testException = new Exception();
+        private final Throwable testException = new Throwable();
 
         @Test
         public void testCompleted() {
@@ -262,7 +262,7 @@ public void testCompleted() {
 
             subject.onNext("four");
             subject.onCompleted();
-            subject.onError(new Exception());
+            subject.onError(new Throwable());
 
             assertCompletedObserver(aObserver);
             // todo bug?            assertNeverObserver(anotherObserver);
@@ -273,14 +273,14 @@ private void assertCompletedObserver(Observer<String> aObserver)
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, times(1)).onNext("two");
             verify(aObserver, times(1)).onNext("three");
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
         private void assertNeverObserver(Observer<String> aObserver)
         {
             verify(aObserver, Mockito.never()).onNext(any(String.class));
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, Mockito.never()).onCompleted();
         }
 
@@ -302,7 +302,7 @@ public void testError() {
             subject.subscribe(anotherObserver);
 
             subject.onNext("four");
-            subject.onError(new Exception());
+            subject.onError(new Throwable());
             subject.onCompleted();
 
             assertErrorObserver(aObserver);
@@ -347,7 +347,7 @@ private void assertCompletedStartingWithThreeObserver(Observer<String> aObserver
             verify(aObserver, Mockito.never()).onNext("one");
             verify(aObserver, Mockito.never()).onNext("two");
             verify(aObserver, times(1)).onNext("three");
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, times(1)).onCompleted();
         }
 
@@ -381,7 +381,7 @@ private void assertObservedUntilTwo(Observer<String> aObserver)
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, times(1)).onNext("two");
             verify(aObserver, Mockito.never()).onNext("three");
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, Mockito.never()).onCompleted();
         }
 
@@ -411,7 +411,7 @@ public void testUnsubscribeAfterOnCompleted() {
             inOrder.verify(anObserver, times(1)).onNext("one");
             inOrder.verify(anObserver, times(1)).onNext("two");
             inOrder.verify(anObserver, times(1)).onCompleted();
-            inOrder.verify(anObserver, Mockito.never()).onError(any(Exception.class));
+            inOrder.verify(anObserver, Mockito.never()).onError(any(Throwable.class));
 
             @SuppressWarnings("unchecked")
             Observer<String> anotherObserver = mock(Observer.class);
@@ -421,7 +421,7 @@ public void testUnsubscribeAfterOnCompleted() {
             inOrder.verify(anotherObserver, Mockito.never()).onNext("one");
             inOrder.verify(anotherObserver, Mockito.never()).onNext("two");
             inOrder.verify(anotherObserver, times(1)).onCompleted();
-            inOrder.verify(anotherObserver, Mockito.never()).onError(any(Exception.class));
+            inOrder.verify(anotherObserver, Mockito.never()).onError(any(Throwable.class));
         }
 
         @Test
@@ -476,7 +476,7 @@ public void call(PublishSubject<Object> DefaultSubject)
                 @Override
                 public void call(PublishSubject<Object> DefaultSubject)
                 {
-                    DefaultSubject.onError(new Exception());
+                    DefaultSubject.onError(new Throwable());
                 }
             }, new Action1<PublishSubject<Object>>()
             {
diff --git a/rxjava-core/src/main/java/rx/subjects/ReplaySubject.java b/rxjava-core/src/main/java/rx/subjects/ReplaySubject.java
index 7d9e13bafc..b6711c15c4 100644
--- a/rxjava-core/src/main/java/rx/subjects/ReplaySubject.java
+++ b/rxjava-core/src/main/java/rx/subjects/ReplaySubject.java
@@ -61,7 +61,7 @@ public final class ReplaySubject<T> extends Subject<T, T>
 {
 
     private boolean isDone = false;
-    private Exception exception = null;
+    private Throwable exception = null;
     private final Map<Subscription, Observer<T>> subscriptions = new HashMap<Subscription, Observer<T>>();
     private final List<T> history = Collections.synchronizedList(new ArrayList<T>());
 
@@ -153,7 +153,7 @@ public void onCompleted()
     }
 
     @Override
-    public void onError(Exception e)
+    public void onError(Throwable e)
     {
         synchronized (subscriptions) {
             if (isDone) {
@@ -181,7 +181,7 @@ public void onNext(T args)
 
     public static class UnitTest {
 
-        private final Exception testException = new Exception();
+        private final Throwable testException = new Throwable();
 
         @SuppressWarnings("unchecked")
         @Test
@@ -198,7 +198,7 @@ public void testCompleted() {
 
             subject.onNext("four");
             subject.onCompleted();
-            subject.onError(new Exception());
+            subject.onError(new Throwable());
 
             assertCompletedObserver(o1);
 
@@ -215,7 +215,7 @@ private void assertCompletedObserver(Observer<String> aObserver)
             inOrder.verify(aObserver, times(1)).onNext("one");
             inOrder.verify(aObserver, times(1)).onNext("two");
             inOrder.verify(aObserver, times(1)).onNext("three");
-            inOrder.verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            inOrder.verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             inOrder.verify(aObserver, times(1)).onCompleted();
             inOrder.verifyNoMoreInteractions();
         }
@@ -234,7 +234,7 @@ public void testError() {
             subject.onError(testException);
 
             subject.onNext("four");
-            subject.onError(new Exception());
+            subject.onError(new Throwable());
             subject.onCompleted();
 
             assertErrorObserver(aObserver);
@@ -307,7 +307,7 @@ private void assertObservedUntilTwo(Observer<String> aObserver)
             verify(aObserver, times(1)).onNext("one");
             verify(aObserver, times(1)).onNext("two");
             verify(aObserver, Mockito.never()).onNext("three");
-            verify(aObserver, Mockito.never()).onError(any(Exception.class));
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
             verify(aObserver, Mockito.never()).onCompleted();
         }
 
@@ -333,7 +333,7 @@ public void call(ReplaySubject<Object> repeatSubject)
                 @Override
                 public void call(ReplaySubject<Object> repeatSubject)
                 {
-                    repeatSubject.onError(new Exception());
+                    repeatSubject.onError(new Throwable());
                 }
             }, new Action1<ReplaySubject<Object>>()
             {
diff --git a/rxjava-core/src/main/java/rx/subjects/UnsubscribeTester.java b/rxjava-core/src/main/java/rx/subjects/UnsubscribeTester.java
index acd7fe1919..30674c9a43 100644
--- a/rxjava-core/src/main/java/rx/subjects/UnsubscribeTester.java
+++ b/rxjava-core/src/main/java/rx/subjects/UnsubscribeTester.java
@@ -96,7 +96,7 @@ public void onCompleted()
             }
 
             @Override
-            public void onError(Exception e)
+            public void onError(Throwable e)
             {
                 test.gotEvent("onError");
             }
@@ -122,7 +122,7 @@ public void onCompleted()
             }
 
             @Override
-            public void onError(Exception e)
+            public void onError(Throwable e)
             {
                 test.doUnsubscribe("onError");
             }
@@ -148,7 +148,7 @@ public void onCompleted()
             }
 
             @Override
-            public void onError(Exception e)
+            public void onError(Throwable e)
             {
                 test.gotEvent("onError");
             }
diff --git a/rxjava-core/src/main/java/rx/subscriptions/CompositeSubscription.java b/rxjava-core/src/main/java/rx/subscriptions/CompositeSubscription.java
index 4753f23acf..873176c8d4 100644
--- a/rxjava-core/src/main/java/rx/subscriptions/CompositeSubscription.java
+++ b/rxjava-core/src/main/java/rx/subscriptions/CompositeSubscription.java
@@ -69,13 +69,13 @@ public synchronized void add(Subscription s) {
     @Override
     public synchronized void unsubscribe() {
         if (unsubscribed.compareAndSet(false, true)) {
-            Collection<Exception> es = null;
+            Collection<Throwable> es = null;
             for (Subscription s : subscriptions) {
                 try {
                     s.unsubscribe();
-                } catch (Exception e) {
+                } catch (Throwable e) {
                     if (es == null) {
-                        es = new ArrayList<Exception>();
+                        es = new ArrayList<Throwable>();
                     }
                     es.add(e);
                 }
diff --git a/rxjava-core/src/main/java/rx/util/CompositeException.java b/rxjava-core/src/main/java/rx/util/CompositeException.java
index c19a5f5ff0..b233a9f90b 100644
--- a/rxjava-core/src/main/java/rx/util/CompositeException.java
+++ b/rxjava-core/src/main/java/rx/util/CompositeException.java
@@ -29,17 +29,17 @@ public class CompositeException extends RuntimeException {
 
     private static final long serialVersionUID = 3026362227162912146L;
 
-    private final List<Exception> exceptions;
+    private final List<Throwable> exceptions;
     private final String message;
 
-    public CompositeException(String messagePrefix, Collection<Exception> errors) {
+    public CompositeException(String messagePrefix, Collection<Throwable> errors) {
         StringBuilder _message = new StringBuilder();
         if (messagePrefix != null) {
             _message.append(messagePrefix).append(" => ");
         }
 
-        List<Exception> _exceptions = new ArrayList<Exception>();
-        for (Exception e : errors) {
+        List<Throwable> _exceptions = new ArrayList<Throwable>();
+        for (Throwable e : errors) {
             _exceptions.add(e);
             if (_message.length() > 0) {
                 _message.append(", ");
@@ -50,11 +50,11 @@ public CompositeException(String messagePrefix, Collection<Exception> errors) {
         this.message = _message.toString();
     }
 
-    public CompositeException(Collection<Exception> errors) {
+    public CompositeException(Collection<Throwable> errors) {
         this(null, errors);
     }
 
-    public List<Exception> getExceptions() {
+    public List<Throwable> getExceptions() {
         return exceptions;
     }
 
diff --git a/rxjava-core/src/main/java/rx/util/OnErrorNotImplementedException.java b/rxjava-core/src/main/java/rx/util/OnErrorNotImplementedException.java
index b84d32bb28..d6124f65d3 100644
--- a/rxjava-core/src/main/java/rx/util/OnErrorNotImplementedException.java
+++ b/rxjava-core/src/main/java/rx/util/OnErrorNotImplementedException.java
@@ -3,7 +3,7 @@
 import rx.Observer;
 
 /**
- * Used for re-throwing {@link Observer#onError(Exception)} when an implementation doesn't exist.
+ * Used for re-throwing {@link Observer#onError(Throwable)} when an implementation doesn't exist.
  * 
  * https://github.com/Netflix/RxJava/issues/198
  * 
diff --git a/rxjava-core/src/main/java/rx/util/functions/Functions.java b/rxjava-core/src/main/java/rx/util/functions/Functions.java
index 53671c210d..4486e7bd26 100644
--- a/rxjava-core/src/main/java/rx/util/functions/Functions.java
+++ b/rxjava-core/src/main/java/rx/util/functions/Functions.java
@@ -52,7 +52,7 @@ private static boolean loadLanguageAdaptor(String name) {
         } catch (ClassNotFoundException e) {
             System.err.println("RxJava => Could not find function language adaptor: " + name + " with path: " + className);
             return false;
-        } catch (Exception e) {
+        } catch (Throwable e) {
             System.err.println("RxJava => Failed trying to initialize function language adaptor: " + className);
             e.printStackTrace();
             return false;
diff --git a/rxjava-core/src/test/java/rx/concurrency/TestSchedulers.java b/rxjava-core/src/test/java/rx/concurrency/TestSchedulers.java
index 661c423fe6..71a9678c67 100644
--- a/rxjava-core/src/test/java/rx/concurrency/TestSchedulers.java
+++ b/rxjava-core/src/test/java/rx/concurrency/TestSchedulers.java
@@ -330,7 +330,7 @@ public void onCompleted() {
             }
 
             @Override
-            public void onError(Exception e) {
+            public void onError(Throwable e) {
                 System.out.println("Error");
             }
 
@@ -491,7 +491,7 @@ public Subscription call(final Observer<String> observer) {
     private static class ConcurrentObserverValidator<T> implements Observer<T> {
 
         final AtomicInteger concurrentCounter = new AtomicInteger();
-        final AtomicReference<Exception> error = new AtomicReference<Exception>();
+        final AtomicReference<Throwable> error = new AtomicReference<Throwable>();
         final CountDownLatch completed = new CountDownLatch(1);
 
         @Override
@@ -500,7 +500,7 @@ public void onCompleted() {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             completed.countDown();
             error.set(e);
         }
diff --git a/rxjava-core/src/test/java/rx/performance/PerformanceTest.java b/rxjava-core/src/test/java/rx/performance/PerformanceTest.java
index 7928776f9a..9d26581e6b 100644
--- a/rxjava-core/src/test/java/rx/performance/PerformanceTest.java
+++ b/rxjava-core/src/test/java/rx/performance/PerformanceTest.java
@@ -231,7 +231,7 @@ public void onNext(Integer i) {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             e.printStackTrace();
         }
 
@@ -260,7 +260,7 @@ public void onNext(String i) {
         }
 
         @Override
-        public void onError(Exception e) {
+        public void onError(Throwable e) {
             e.printStackTrace();
         }
 

From 97fafb02d98ba4f5329e34cbed532b65c087e9ee Mon Sep 17 00:00:00 2001
From: Ben Christensen <benjchristensen@netflix.com>
Date: Wed, 31 Jul 2013 21:20:46 -0700
Subject: [PATCH 4/8] OnExceptionResumeNext

See https://github.com/Netflix/RxJava/issues/296#issuecomment-21358856 for context.
---
 rxjava-core/src/main/java/rx/Observable.java  |  63 ++++
 ...ionOnExceptionResumeNextViaObservable.java | 332 ++++++++++++++++++
 2 files changed, 395 insertions(+)
 create mode 100644 rxjava-core/src/main/java/rx/operators/OperationOnExceptionResumeNextViaObservable.java

diff --git a/rxjava-core/src/main/java/rx/Observable.java b/rxjava-core/src/main/java/rx/Observable.java
index 876ff5de65..fecc5c41f6 100644
--- a/rxjava-core/src/main/java/rx/Observable.java
+++ b/rxjava-core/src/main/java/rx/Observable.java
@@ -39,6 +39,7 @@
 import rx.observables.BlockingObservable;
 import rx.observables.ConnectableObservable;
 import rx.observables.GroupedObservable;
+import rx.operators.OperationOnExceptionResumeNextViaObservable;
 import rx.operators.SafeObservableSubscription;
 import rx.operators.SafeObserver;
 import rx.operators.OperationAll;
@@ -1869,6 +1870,36 @@ public static <T> Observable<T> onErrorResumeNext(final Observable<T> that, fina
     public static <T> Observable<T> onErrorReturn(final Observable<T> that, Func1<Throwable, T> resumeFunction) {
         return create(OperationOnErrorReturn.onErrorReturn(that, resumeFunction));
     }
+    
+    /**
+     * Instruct an Observable to pass control to another Observable rather than invoking {@link Observer#onError onError} if it encounters an error of type {@link java.lang.Exception}.
+     * <p>
+     * This differs from {@link #onErrorResumeNext} in that this one does not handle {@link java.lang.Throwable} or {@link java.lang.Error} but lets those continue through.
+     * <p>
+     * <img width="640" src="https://raw.github.com/wiki/Netflix/RxJava/images/rx-operators/onErrorResumeNext.png">
+     * <p>
+     * By default, when an Observable encounters an error that prevents it from emitting the
+     * expected item to its Observer, the Observable invokes its {@link Observer}'s {@code onError} method, and then quits without invoking any more of its Observer's
+     * methods. The {@code onErrorResumeNext} method changes this behavior. If you pass an
+     * Observable ({@code resumeSequence}) to {@code onErrorResumeNext}, if the original
+     * Observable encounters an error, instead of invoking its Observer's <code>onError</code>
+     * method, it will instead relinquish control to this new Observable, which will invoke the
+     * Observer's {@link Observer#onNext onNext} method if it is able to do so. In such a case,
+     * because no Observable necessarily invokes {@code onError}, the Observer may never know
+     * that an error happened.
+     * <p>
+     * You can use this to prevent errors from propagating or to supply fallback data should errors
+     * be encountered.
+     * 
+     * @param that
+     *            the source Observable
+     * @param resumeSequence
+     *            a Observable that will take over if the source Observable encounters an error
+     * @return an Observable, identical to the source Observable with its behavior modified as described
+     */
+    public static <T> Observable<T> onExceptionResumeNext(final Observable<T> that, final Observable<T> resumeSequence) {
+        return create(OperationOnExceptionResumeNextViaObservable.onExceptionResumeNextViaObservable(that, resumeSequence));
+    }
 
     /**
      * Returns a {@link ConnectableObservable} that shares a single subscription to the underlying
@@ -3640,6 +3671,38 @@ public Observable<T> call(Throwable e) {
     public Observable<T> onErrorResumeNext(final Observable<T> resumeSequence) {
         return onErrorResumeNext(this, resumeSequence);
     }
+    
+    /**
+     * Instruct an Observable to pass control to another Observable rather than invoking
+     * {@link Observer#onError onError} if it encounters an error of type {@link java.lang.Exception}.
+     * <p>
+     * This differs from {@link #onErrorResumeNext} in that this one does not handle {@link java.lang.Throwable} or {@link java.lang.Error} but lets those continue through.
+     * <p>
+     * <img width="640" src="https://raw.github.com/wiki/Netflix/RxJava/images/rx-operators/onErrorResumeNext.png">
+     * <p>
+     * By default, when an Observable encounters an error that prevents it from emitting the
+     * expected item to its {@link Observer}, the Observable invokes its Observer's
+     * <code>onError</code> method, and then quits without invoking any more of its Observer's
+     * methods. The <code>onErrorResumeNext</code> method changes this behavior. If you pass
+     * another Observable (<code>resumeSequence</code>) to an Observable's
+     * <code>onErrorResumeNext</code> method, if the original Observable encounters an error,
+     * instead of invoking its Observer's <code>onError</code> method, it will instead relinquish
+     * control to <code>resumeSequence</code> which will invoke the Observer's
+     * {@link Observer#onNext onNext} method if it is able to do so. In such a case, because no
+     * Observable necessarily invokes <code>onError</code>, the Observer may never know that an
+     * error happened.
+     * <p>
+     * You can use this to prevent errors from propagating or to supply fallback data should errors
+     * be encountered.
+     *
+     * @param resumeSequence
+     *            a function that returns an Observable that will take over if the source Observable
+     *            encounters an error
+     * @return the original Observable, with appropriately modified behavior
+     */
+    public Observable<T> onExceptionResumeNext(final Observable<T> resumeSequence) {
+        return onExceptionResumeNext(this, resumeSequence);
+    }
 
     /**
      * Instruct an Observable to emit an item (returned by a specified function) rather than
diff --git a/rxjava-core/src/main/java/rx/operators/OperationOnExceptionResumeNextViaObservable.java b/rxjava-core/src/main/java/rx/operators/OperationOnExceptionResumeNextViaObservable.java
new file mode 100644
index 0000000000..9f633d0a2f
--- /dev/null
+++ b/rxjava-core/src/main/java/rx/operators/OperationOnExceptionResumeNextViaObservable.java
@@ -0,0 +1,332 @@
+/**
+ * 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.operators;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import rx.Observable;
+import rx.Observer;
+import rx.Subscription;
+import rx.util.functions.Func1;
+
+/**
+ * Instruct an Observable to pass control to another Observable rather than invoking
+ * <code>onError</code> if it encounters an error of type {@link java.lang.Exception}.
+ * <p>
+ * This differs from {@link Observable#onErrorResumeNext} in that this one does not handle {@link java.lang.Throwable} or {@link java.lang.Error} but lets those continue through.
+ * <p>
+ * <img width="640" src="https://github.com/Netflix/RxJava/wiki/images/rx-operators/onErrorResumeNext.png">
+ * <p>
+ * By default, when an Observable encounters an error that prevents it from emitting the expected
+ * item to its Observer, the Observable invokes its Observer's <code>onError</code> method, and
+ * then quits without invoking any more of its Observer's methods. The onErrorResumeNext operation
+ * changes this behavior. If you pass an Observable (resumeSequence) to onErrorResumeNext, if the
+ * source Observable encounters an error, instead of invoking its Observer's <code>onError</code>
+ * method, it will instead relinquish control to this new Observable, which will invoke the
+ * Observer's <code>onNext</code> method if it is able to do so. In such a case, because no
+ * Observable necessarily invokes <code>onError</code>, the Observer may never know that an error
+ * happened.
+ * <p>
+ * You can use this to prevent errors from propagating or to supply fallback data should errors be
+ * encountered.
+ */
+public final class OperationOnExceptionResumeNextViaObservable<T> {
+
+    public static <T> Func1<Observer<T>, Subscription> onExceptionResumeNextViaObservable(Observable<T> originalSequence, Observable<T> resumeSequence) {
+        return new OnExceptionResumeNextViaObservable<T>(originalSequence, resumeSequence);
+    }
+
+    private static class OnExceptionResumeNextViaObservable<T> implements Func1<Observer<T>, Subscription> {
+
+        private final Observable<T> resumeSequence;
+        private final Observable<T> originalSequence;
+
+        public OnExceptionResumeNextViaObservable(Observable<T> originalSequence, Observable<T> resumeSequence) {
+            this.resumeSequence = resumeSequence;
+            this.originalSequence = originalSequence;
+        }
+
+        public Subscription call(final Observer<T> observer) {
+            final SafeObservableSubscription subscription = new SafeObservableSubscription();
+
+            // AtomicReference since we'll be accessing/modifying this across threads so we can switch it if needed
+            final AtomicReference<SafeObservableSubscription> subscriptionRef = new AtomicReference<SafeObservableSubscription>(subscription);
+
+            // subscribe to the original Observable and remember the subscription
+            subscription.wrap(originalSequence.subscribe(new Observer<T>() {
+                public void onNext(T value) {
+                    // forward the successful calls unless resumed
+                    if (subscriptionRef.get() == subscription)
+                        observer.onNext(value);
+                }
+
+                /**
+                 * When we receive java.lang.Exception, instead of passing the onError forward, we intercept and "resume" with the resumeSequence.
+                 * For Throwable and Error we pass thru.
+                 */
+                public void onError(Throwable ex) {
+                    if (ex instanceof Exception) {
+                        /* remember what the current subscription is so we can determine if someone unsubscribes concurrently */
+                        SafeObservableSubscription currentSubscription = subscriptionRef.get();
+                        // check that we have not been unsubscribed and not already resumed before we can process the error
+                        if (currentSubscription == subscription) {
+                            /* error occurred, so switch subscription to the 'resumeSequence' */
+                            SafeObservableSubscription innerSubscription = new SafeObservableSubscription(resumeSequence.subscribe(observer));
+                            /* we changed the sequence, so also change the subscription to the one of the 'resumeSequence' instead */
+                            if (!subscriptionRef.compareAndSet(currentSubscription, innerSubscription)) {
+                                // we failed to set which means 'subscriptionRef' was set to NULL via the unsubscribe below
+                                // so we want to immediately unsubscribe from the resumeSequence we just subscribed to
+                                innerSubscription.unsubscribe();
+                            }
+                        }
+                    } else {
+                        observer.onError(ex);
+                    }
+                }
+
+                public void onCompleted() {
+                    // forward the successful calls unless resumed
+                    if (subscriptionRef.get() == subscription)
+                        observer.onCompleted();
+                }
+            }));
+
+            return new Subscription() {
+                public void unsubscribe() {
+                    // this will get either the original, or the resumeSequence one and unsubscribe on it
+                    Subscription s = subscriptionRef.getAndSet(null);
+                    if (s != null) {
+                        s.unsubscribe();
+                    }
+                }
+            };
+        }
+    }
+
+    public static class UnitTest {
+
+        @Test
+        public void testResumeNextWithException() {
+            Subscription s = mock(Subscription.class);
+            // Trigger failure on second element
+            TestObservable w = new TestObservable(s, "one", "EXCEPTION", "two", "three");
+            Observable<String> resume = Observable.from("twoResume", "threeResume");
+            Observable<String> observable = Observable.create(onExceptionResumeNextViaObservable(w, resume));
+
+            @SuppressWarnings("unchecked")
+            Observer<String> aObserver = mock(Observer.class);
+            observable.subscribe(aObserver);
+
+            try {
+                w.t.join();
+            } catch (InterruptedException e) {
+                fail(e.getMessage());
+            }
+
+            verify(aObserver, times(1)).onNext("one");
+            verify(aObserver, Mockito.never()).onNext("two");
+            verify(aObserver, Mockito.never()).onNext("three");
+            verify(aObserver, times(1)).onNext("twoResume");
+            verify(aObserver, times(1)).onNext("threeResume");
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
+            verify(aObserver, times(1)).onCompleted();
+            verifyNoMoreInteractions(aObserver);
+        }
+
+        @Test
+        public void testResumeNextWithRuntimeException() {
+            Subscription s = mock(Subscription.class);
+            // Trigger failure on second element
+            TestObservable w = new TestObservable(s, "one", "RUNTIMEEXCEPTION", "two", "three");
+            Observable<String> resume = Observable.from("twoResume", "threeResume");
+            Observable<String> observable = Observable.create(onExceptionResumeNextViaObservable(w, resume));
+
+            @SuppressWarnings("unchecked")
+            Observer<String> aObserver = mock(Observer.class);
+            observable.subscribe(aObserver);
+
+            try {
+                w.t.join();
+            } catch (InterruptedException e) {
+                fail(e.getMessage());
+            }
+
+            verify(aObserver, times(1)).onNext("one");
+            verify(aObserver, Mockito.never()).onNext("two");
+            verify(aObserver, Mockito.never()).onNext("three");
+            verify(aObserver, times(1)).onNext("twoResume");
+            verify(aObserver, times(1)).onNext("threeResume");
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
+            verify(aObserver, times(1)).onCompleted();
+            verifyNoMoreInteractions(aObserver);
+        }
+
+        @Test
+        public void testThrowablePassesThru() {
+            Subscription s = mock(Subscription.class);
+            // Trigger failure on second element
+            TestObservable w = new TestObservable(s, "one", "THROWABLE", "two", "three");
+            Observable<String> resume = Observable.from("twoResume", "threeResume");
+            Observable<String> observable = Observable.create(onExceptionResumeNextViaObservable(w, resume));
+
+            @SuppressWarnings("unchecked")
+            Observer<String> aObserver = mock(Observer.class);
+            observable.subscribe(aObserver);
+
+            try {
+                w.t.join();
+            } catch (InterruptedException e) {
+                fail(e.getMessage());
+            }
+
+            verify(aObserver, times(1)).onNext("one");
+            verify(aObserver, never()).onNext("two");
+            verify(aObserver, never()).onNext("three");
+            verify(aObserver, never()).onNext("twoResume");
+            verify(aObserver, never()).onNext("threeResume");
+            verify(aObserver, times(1)).onError(any(Throwable.class));
+            verify(aObserver, never()).onCompleted();
+            verifyNoMoreInteractions(aObserver);
+        }
+
+        @Test
+        public void testErrorPassesThru() {
+            Subscription s = mock(Subscription.class);
+            // Trigger failure on second element
+            TestObservable w = new TestObservable(s, "one", "ERROR", "two", "three");
+            Observable<String> resume = Observable.from("twoResume", "threeResume");
+            Observable<String> observable = Observable.create(onExceptionResumeNextViaObservable(w, resume));
+
+            @SuppressWarnings("unchecked")
+            Observer<String> aObserver = mock(Observer.class);
+            observable.subscribe(aObserver);
+
+            try {
+                w.t.join();
+            } catch (InterruptedException e) {
+                fail(e.getMessage());
+            }
+
+            verify(aObserver, times(1)).onNext("one");
+            verify(aObserver, never()).onNext("two");
+            verify(aObserver, never()).onNext("three");
+            verify(aObserver, never()).onNext("twoResume");
+            verify(aObserver, never()).onNext("threeResume");
+            verify(aObserver, times(1)).onError(any(Throwable.class));
+            verify(aObserver, never()).onCompleted();
+            verifyNoMoreInteractions(aObserver);
+        }
+
+        @Test
+        public void testMapResumeAsyncNext() {
+            Subscription sr = mock(Subscription.class);
+            // Trigger multiple failures
+            Observable<String> w = Observable.from("one", "fail", "two", "three", "fail");
+            // Resume Observable is async
+            TestObservable resume = new TestObservable(sr, "twoResume", "threeResume");
+
+            // Introduce map function that fails intermittently (Map does not prevent this when the observer is a
+            //  rx.operator incl onErrorResumeNextViaObservable)
+            w = w.map(new Func1<String, String>() {
+                public String call(String s) {
+                    if ("fail".equals(s))
+                        throw new RuntimeException("Forced Failure");
+                    System.out.println("BadMapper:" + s);
+                    return s;
+                }
+            });
+
+            Observable<String> observable = Observable.create(onExceptionResumeNextViaObservable(w, resume));
+
+            @SuppressWarnings("unchecked")
+            Observer<String> aObserver = mock(Observer.class);
+            observable.subscribe(aObserver);
+
+            try {
+                // if the thread gets started (which it shouldn't if it's working correctly)
+                if (resume.t != null) {
+                    resume.t.join();
+                }
+            } catch (InterruptedException e) {
+                fail(e.getMessage());
+            }
+
+            verify(aObserver, times(1)).onNext("one");
+            verify(aObserver, never()).onNext("two");
+            verify(aObserver, never()).onNext("three");
+            verify(aObserver, times(1)).onNext("twoResume");
+            verify(aObserver, times(1)).onNext("threeResume");
+            verify(aObserver, Mockito.never()).onError(any(Throwable.class));
+            verify(aObserver, times(1)).onCompleted();
+        }
+
+        private static class TestObservable extends Observable<String> {
+
+            final Subscription s;
+            final String[] values;
+            Thread t = null;
+
+            public TestObservable(Subscription s, String... values) {
+                this.s = s;
+                this.values = values;
+            }
+
+            @Override
+            public Subscription subscribe(final Observer<String> observer) {
+                System.out.println("TestObservable subscribed to ...");
+                t = new Thread(new Runnable() {
+
+                    @Override
+                    public void run() {
+                        try {
+                            System.out.println("running TestObservable thread");
+                            for (String s : values) {
+                                if ("EXCEPTION".equals(s))
+                                    throw new Exception("Forced Exception");
+                                else if ("RUNTIMEEXCEPTION".equals(s))
+                                    throw new RuntimeException("Forced RuntimeException");
+                                else if ("ERROR".equals(s))
+                                    throw new Error("Forced Error");
+                                else if ("THROWABLE".equals(s))
+                                    throw new Throwable("Forced Throwable");
+                                System.out.println("TestObservable onNext: " + s);
+                                observer.onNext(s);
+                            }
+                            System.out.println("TestObservable onCompleted");
+                            observer.onCompleted();
+                        } catch (Throwable e) {
+                            System.out.println("TestObservable onError: " + e);
+                            observer.onError(e);
+                        }
+                    }
+
+                });
+                System.out.println("starting TestObservable thread");
+                t.start();
+                System.out.println("done starting TestObservable thread");
+                return s;
+            }
+
+        }
+    }
+}

From 349c11ef76b979a5dc541e16552599e7feed5af5 Mon Sep 17 00:00:00 2001
From: Ben Christensen <benjchristensen@netflix.com>
Date: Thu, 1 Aug 2013 09:42:17 -0700
Subject: [PATCH 5/8] Rename exception to throwable to be clear

---
 rxjava-core/src/main/java/rx/Notification.java | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/rxjava-core/src/main/java/rx/Notification.java b/rxjava-core/src/main/java/rx/Notification.java
index f1dbef8ad9..ad6b81c002 100644
--- a/rxjava-core/src/main/java/rx/Notification.java
+++ b/rxjava-core/src/main/java/rx/Notification.java
@@ -23,7 +23,7 @@
 public class Notification<T> {
 
     private final Kind kind;
-    private final Throwable exception;
+    private final Throwable throwable;
     private final T value;
 
     /**
@@ -34,7 +34,7 @@ public class Notification<T> {
      */
     public Notification(T value) {
         this.value = value;
-        this.exception = null;
+        this.throwable = null;
         this.kind = Kind.OnNext;
     }
 
@@ -45,7 +45,7 @@ public Notification(T value) {
      *            The exception passed to the onError notification.
      */
     public Notification(Throwable exception) {
-        this.exception = exception;
+        this.throwable = exception;
         this.value = null;
         this.kind = Kind.OnError;
     }
@@ -54,7 +54,7 @@ public Notification(Throwable exception) {
      * A constructor used to represent an onCompleted notification.
      */
     public Notification() {
-        this.exception = null;
+        this.throwable = null;
         this.value = null;
         this.kind = Kind.OnCompleted;
     }
@@ -65,7 +65,7 @@ public Notification() {
      * @return Throwable associated with an onError notification.
      */
     public Throwable getThrowable() {
-        return exception;
+        return throwable;
     }
 
     /**
@@ -92,7 +92,7 @@ public boolean hasValue() {
      * @return a value indicating whether this notification has an exception.
      */
     public boolean hasException() {
-        return isOnError() && exception != null;
+        return isOnError() && throwable != null;
     }
 
     /**

From 0531b8bff5c14d9504beefb4ad47f473e3a22932 Mon Sep 17 00:00:00 2001
From: Ben Christensen <benjchristensen@netflix.com>
Date: Thu, 1 Aug 2013 09:43:06 -0700
Subject: [PATCH 6/8] Change hasException to hasThrowable

---
 rxjava-core/src/main/java/rx/Notification.java | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/rxjava-core/src/main/java/rx/Notification.java b/rxjava-core/src/main/java/rx/Notification.java
index ad6b81c002..866ed06450 100644
--- a/rxjava-core/src/main/java/rx/Notification.java
+++ b/rxjava-core/src/main/java/rx/Notification.java
@@ -91,7 +91,7 @@ public boolean hasValue() {
      * 
      * @return a value indicating whether this notification has an exception.
      */
-    public boolean hasException() {
+    public boolean hasThrowable() {
         return isOnError() && throwable != null;
     }
 
@@ -125,7 +125,7 @@ public String toString() {
         StringBuilder str = new StringBuilder("[").append(super.toString()).append(" ").append(getKind());
         if (hasValue())
             str.append(" ").append(getValue());
-        if (hasException())
+        if (hasThrowable())
             str.append(" ").append(getThrowable().getMessage());
         str.append("]");
         return str.toString();
@@ -136,7 +136,7 @@ public int hashCode() {
         int hash = getKind().hashCode();
         if (hasValue())
             hash = hash * 31 + getValue().hashCode();
-        if (hasException())
+        if (hasThrowable())
             hash = hash * 31 + getThrowable().hashCode();
         return hash;
     }
@@ -154,7 +154,7 @@ public boolean equals(Object obj) {
             return false;
         if (hasValue() && !getValue().equals(notification.getValue()))
             return false;
-        if (hasException() && !getThrowable().equals(notification.getThrowable()))
+        if (hasThrowable() && !getThrowable().equals(notification.getThrowable()))
             return false;
         return true;
     }

From 87e308ad16e0e9649efa773f5056f373c7b95336 Mon Sep 17 00:00:00 2001
From: Ben Christensen <benjchristensen@netflix.com>
Date: Thu, 1 Aug 2013 09:51:30 -0700
Subject: [PATCH 7/8] Add Error propagation now that we use Throwable.

---
 rxjava-core/src/main/java/rx/util/Exceptions.java | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/rxjava-core/src/main/java/rx/util/Exceptions.java b/rxjava-core/src/main/java/rx/util/Exceptions.java
index 6fb97f1d1f..4e17fb996c 100644
--- a/rxjava-core/src/main/java/rx/util/Exceptions.java
+++ b/rxjava-core/src/main/java/rx/util/Exceptions.java
@@ -21,8 +21,18 @@ private Exceptions() {
     }
 
     public static RuntimeException propagate(Throwable t) {
+        /**
+         * The return type of RuntimeException is a trick for code to be like this:
+         * 
+         * throw Exceptions.propagate(e);
+         * 
+         * Even though nothing will return and throw via that 'throw', it allows the code to look like it
+         * so it's easy to read and understand that it will always result in a throw.
+         */
         if (t instanceof RuntimeException) {
             throw (RuntimeException) t;
+        } else if (t instanceof Error) {
+            throw (Error) t;
         } else {
             throw new RuntimeException(t);
         }

From 5316bcc1094f54f93821a1c5176086fa9880d691 Mon Sep 17 00:00:00 2001
From: Ben Christensen <benjchristensen@netflix.com>
Date: Thu, 1 Aug 2013 10:06:03 -0700
Subject: [PATCH 8/8] Test with Error instead of RuntimeException
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

… test the Throwable catch instead of Exception.
---
 rxjava-core/src/main/java/rx/Observable.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rxjava-core/src/main/java/rx/Observable.java b/rxjava-core/src/main/java/rx/Observable.java
index fecc5c41f6..f6431926e9 100644
--- a/rxjava-core/src/main/java/rx/Observable.java
+++ b/rxjava-core/src/main/java/rx/Observable.java
@@ -4895,7 +4895,7 @@ public Subscription call(final Observer<String> observer) {
                         @Override
                         public void run() {
                             try {
-                                observer.onError(new RuntimeException("failure"));
+                                observer.onError(new Error("failure"));
                             } catch (Throwable e) {
                                 // without an onError handler it has to just throw on whatever thread invokes it
                                 exception.set(e);