title: RxJava2's UndeliverableException and disposed streams
body: <p>I feel like I'm not understanding something about RxJava2's error-handling. (btw, I have read <a href="https://stackoverflow.com/questions/43525052/rxjava2-observable-take-throws-undeliverableexception">RxJava2 observable take throws UndeliverableException</a> and I understand what happens, but not exactly why or if there's a better way to deal with it than what I discuss below. I have also seen <a href="https://stackoverflow.com/questions/43532034/runtimeexception-thrown-and-not-caught-in-rxjava2-single-after-it-has-been-dispo">RuntimeException thrown and not caught in RxJava2 Single after it has been disposed</a> and it doesn't seem exactly relevant.)</p>
  
  <p>Let's say I have the following, very much simplified example:</p>
  
  <pre><code>val sub = Observable.fromCallable(callableThatCanReturnNull)
                      .subscribe({ println(it) }, { System.err.println(it) })
  </code></pre>
  
  <p>And the following sequence of events happens, in order:</p>
  
  <ol>
  <li><code>sub.dispose()</code></li>
  <li>That darn <code>Callable</code> returns null.</li>
  </ol>
  
  <p>Looking at the RxJava2 source, I see this:</p>
  
  <pre><code>@Override
  public void subscribeActual(Observer&lt;? super T&gt; s) {
      DeferredScalarDisposable&lt;T&gt; d = new DeferredScalarDisposable&lt;T&gt;(s);
      s.onSubscribe(d);
      if (d.isDisposed()) {
          return;
      }
      T value;
      try {
          value = ObjectHelper.requireNonNull(callable.call(), "Callable returned null");
      } catch (Throwable e) {
          Exceptions.throwIfFatal(e);
          if (!d.isDisposed()) {
              s.onError(e);
          } else {
              RxJavaPlugins.onError(e);
          }
          return;
      }
      d.complete(value);
  }
  </code></pre>
  
  <p>Apparently sometime between the first <code>d.isDisposed()</code> check and the second, <code>d</code> is disposed, and so we hit <code>RxJavaPlugins.onError(e)</code> with <code>e</code> being a <code>NullPointerException</code> (from <code>ObjectHelper.requireNonNull()</code>). If we have not called <code>RxJavaPlugins.setErrorHandler()</code> with something, then the default behavior is to throw a fatal exception that will crash the application. This seems Bad (tm). My current approach is the following:</p>
  
  <pre><code>    GlobalErrorFilter errorFilter = new GlobalErrorFilter(BuildConfig.DEBUG /* alwaysCrash */);
      RxJavaPlugins.setErrorHandler(t -&gt; {
          if (errorFilter.filter(t)) {
              // Crash in some cases
              throw new RuntimeException(t);
          } else {
              // Just log it in others
              Logger.e("RxError", t, "Ignoring uncaught Rx exception: %s", t.getLocalizedMessage());
          }
      });
  </code></pre>
  
  <p>And my <code>GlobalErrorFilter</code> takes into consideration this <code>fromCallable</code> case and also <code>UndeliverableException</code>. In fact, it looks like this:</p>
  
  <pre><code>class GlobalErrorFilter(private val alwaysCrash: Boolean = false) {
  
      /**
       * Returns `true` if app should crash; `false` otherwise. Prefers to return `true`.
       */
      fun filter(t: Throwable) = when {
          alwaysCrash -&gt; true
          t is UndeliverableException -&gt; false
          t.localizedMessage.contains("Callable returned null") -&gt; false
          else -&gt; true
      }
  }
  </code></pre>
  
  <p>This <em>feels</em> really hackish. What I <em>want</em> is to tell RxJava that if I have disposed of an observable, I <em>do not care</em> whether (1) it emits new items (2) it completes (3) it onErrors. I just don't care. Is there a way to do that without this global error handler?</p>