diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableCreate.java b/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableCreate.java index 61ef4b15d2..4004630756 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableCreate.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableCreate.java @@ -20,6 +20,7 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Cancellable; import io.reactivex.rxjava3.internal.disposables.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class CompletableCreate extends Completable { @@ -81,7 +82,7 @@ public void onError(Throwable t) { @Override public boolean tryOnError(Throwable t) { if (t == null) { - t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + t = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } if (get() != DisposableHelper.DISPOSED) { Disposable d = getAndSet(DisposableHelper.DISPOSED); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMerge.java b/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMerge.java index ba28e2b050..9d916d84b6 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMerge.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMerge.java @@ -22,7 +22,6 @@ import io.reactivex.rxjava3.internal.disposables.DisposableHelper; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; import io.reactivex.rxjava3.internal.util.AtomicThrowable; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class CompletableMerge extends Completable { final Publisher source; @@ -51,7 +50,7 @@ static final class CompletableMergeSubscriber final int maxConcurrency; final boolean delayErrors; - final AtomicThrowable error; + final AtomicThrowable errors; final CompositeDisposable set; @@ -62,7 +61,7 @@ static final class CompletableMergeSubscriber this.maxConcurrency = maxConcurrency; this.delayErrors = delayErrors; this.set = new CompositeDisposable(); - this.error = new AtomicThrowable(); + this.errors = new AtomicThrowable(); lazySet(1); } @@ -70,7 +69,7 @@ static final class CompletableMergeSubscriber public void dispose() { upstream.cancel(); set.dispose(); - error.tryTerminateAndReport(); + errors.tryTerminateAndReport(); } @Override @@ -105,20 +104,16 @@ public void onError(Throwable t) { if (!delayErrors) { set.dispose(); - if (error.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (getAndSet(0) > 0) { - error.tryTerminateConsumer(downstream); + errors.tryTerminateConsumer(downstream); } - } else { - RxJavaPlugins.onError(t); } } else { - if (error.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (decrementAndGet() == 0) { - error.tryTerminateConsumer(downstream); + errors.tryTerminateConsumer(downstream); } - } else { - RxJavaPlugins.onError(t); } } } @@ -126,7 +121,7 @@ public void onError(Throwable t) { @Override public void onComplete() { if (decrementAndGet() == 0) { - error.tryTerminateConsumer(downstream); + errors.tryTerminateConsumer(downstream); } } @@ -136,24 +131,20 @@ void innerError(MergeInnerObserver inner, Throwable t) { upstream.cancel(); set.dispose(); - if (error.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (getAndSet(0) > 0) { - error.tryTerminateConsumer(downstream); + errors.tryTerminateConsumer(downstream); } - } else { - RxJavaPlugins.onError(t); } } else { - if (error.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (decrementAndGet() == 0) { - error.tryTerminateConsumer(downstream); + errors.tryTerminateConsumer(downstream); } else { if (maxConcurrency != Integer.MAX_VALUE) { upstream.request(1); } } - } else { - RxJavaPlugins.onError(t); } } } @@ -161,7 +152,7 @@ void innerError(MergeInnerObserver inner, Throwable t) { void innerComplete(MergeInnerObserver inner) { set.delete(inner); if (decrementAndGet() == 0) { - error.tryTerminateConsumer(downstream); + errors.tryTerminateConsumer(downstream); } else { if (maxConcurrency != Integer.MAX_VALUE) { upstream.request(1); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMergeDelayErrorArray.java b/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMergeDelayErrorArray.java index a3facef60c..549fd10a48 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMergeDelayErrorArray.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMergeDelayErrorArray.java @@ -18,7 +18,6 @@ import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.disposables.*; import io.reactivex.rxjava3.internal.util.AtomicThrowable; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class CompletableMergeDelayErrorArray extends Completable { @@ -33,8 +32,8 @@ public void subscribeActual(final CompletableObserver observer) { final CompositeDisposable set = new CompositeDisposable(); final AtomicInteger wip = new AtomicInteger(sources.length + 1); - final AtomicThrowable error = new AtomicThrowable(); - set.add(new TryTerminateAndReportDisposable(error)); + final AtomicThrowable errors = new AtomicThrowable(); + set.add(new TryTerminateAndReportDisposable(errors)); observer.onSubscribe(set); @@ -45,16 +44,16 @@ public void subscribeActual(final CompletableObserver observer) { if (c == null) { Throwable ex = new NullPointerException("A completable source is null"); - error.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); wip.decrementAndGet(); continue; } - c.subscribe(new MergeInnerCompletableObserver(observer, set, error, wip)); + c.subscribe(new MergeInnerCompletableObserver(observer, set, errors, wip)); } if (wip.decrementAndGet() == 0) { - error.tryTerminateConsumer(observer); + errors.tryTerminateConsumer(observer); } } @@ -79,14 +78,14 @@ static final class MergeInnerCompletableObserver implements CompletableObserver { final CompletableObserver downstream; final CompositeDisposable set; - final AtomicThrowable error; + final AtomicThrowable errors; final AtomicInteger wip; MergeInnerCompletableObserver(CompletableObserver observer, CompositeDisposable set, AtomicThrowable error, AtomicInteger wip) { this.downstream = observer; this.set = set; - this.error = error; + this.errors = error; this.wip = wip; } @@ -97,10 +96,8 @@ public void onSubscribe(Disposable d) { @Override public void onError(Throwable e) { - if (error.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { tryTerminate(); - } else { - RxJavaPlugins.onError(e); } } @@ -111,7 +108,7 @@ public void onComplete() { void tryTerminate() { if (wip.decrementAndGet() == 0) { - error.tryTerminateConsumer(downstream); + errors.tryTerminateConsumer(downstream); } } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMergeDelayErrorIterable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMergeDelayErrorIterable.java index 63786f6f0e..6d420cf044 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMergeDelayErrorIterable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/completable/CompletableMergeDelayErrorIterable.java @@ -49,8 +49,8 @@ public void subscribeActual(final CompletableObserver observer) { final AtomicInteger wip = new AtomicInteger(1); - final AtomicThrowable error = new AtomicThrowable(); - set.add(new TryTerminateAndReportDisposable(error)); + final AtomicThrowable errors = new AtomicThrowable(); + set.add(new TryTerminateAndReportDisposable(errors)); for (;;) { if (set.isDisposed()) { @@ -62,7 +62,7 @@ public void subscribeActual(final CompletableObserver observer) { b = iterator.hasNext(); } catch (Throwable e) { Exceptions.throwIfFatal(e); - error.addThrowable(e); + errors.tryAddThrowableOrReport(e); break; } @@ -80,7 +80,7 @@ public void subscribeActual(final CompletableObserver observer) { c = ObjectHelper.requireNonNull(iterator.next(), "The iterator returned a null CompletableSource"); } catch (Throwable e) { Exceptions.throwIfFatal(e); - error.addThrowable(e); + errors.tryAddThrowableOrReport(e); break; } @@ -90,11 +90,11 @@ public void subscribeActual(final CompletableObserver observer) { wip.getAndIncrement(); - c.subscribe(new MergeInnerCompletableObserver(observer, set, error, wip)); + c.subscribe(new MergeInnerCompletableObserver(observer, set, errors, wip)); } if (wip.decrementAndGet() == 0) { - error.tryTerminateConsumer(observer); + errors.tryTerminateConsumer(observer); } } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableBufferBoundary.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableBufferBoundary.java index 62e11eb2c3..4e8103e1a6 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableBufferBoundary.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableBufferBoundary.java @@ -130,15 +130,13 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { subscribers.dispose(); synchronized (this) { buffers = null; } done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -264,8 +262,7 @@ void drain() { boolean d = done; if (d && errors.get() != null) { q.clear(); - Throwable ex = errors.terminate(); - a.onError(ex); + errors.tryTerminateConsumer(a); return; } @@ -294,8 +291,7 @@ void drain() { if (done) { if (errors.get() != null) { q.clear(); - Throwable ex = errors.terminate(); - a.onError(ex); + errors.tryTerminateConsumer(a); return; } else if (q.isEmpty()) { a.onComplete(); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMap.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMap.java index 6aea36d5d2..a11f206dde 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMap.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMap.java @@ -24,7 +24,6 @@ import io.reactivex.rxjava3.internal.queue.SpscArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.*; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class FlowableConcatMap extends AbstractFlowableWithUpstream { @@ -196,14 +195,12 @@ void subscribeActual() { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { inner.cancel(); if (getAndIncrement() == 0) { errors.tryTerminateConsumer(downstream); } - } else { - RxJavaPlugins.onError(t); } } @@ -220,14 +217,12 @@ public void innerNext(R value) { @Override public void innerError(Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { upstream.cancel(); if (getAndIncrement() == 0) { errors.tryTerminateConsumer(downstream); } - } else { - RxJavaPlugins.onError(e); } } @@ -266,7 +261,7 @@ void drain() { } catch (Throwable e) { Exceptions.throwIfFatal(e); upstream.cancel(); - errors.addThrowable(e); + errors.tryAddThrowableOrReport(e); errors.tryTerminateConsumer(downstream); return; } @@ -287,7 +282,7 @@ void drain() { Exceptions.throwIfFatal(e); upstream.cancel(); - errors.addThrowable(e); + errors.tryAddThrowableOrReport(e); errors.tryTerminateConsumer(downstream); return; } @@ -313,7 +308,7 @@ void drain() { } catch (Throwable e) { Exceptions.throwIfFatal(e); upstream.cancel(); - errors.addThrowable(e); + errors.tryAddThrowableOrReport(e); errors.tryTerminateConsumer(downstream); return; } @@ -400,11 +395,9 @@ void subscribeActual() { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -415,15 +408,13 @@ public void innerNext(R value) { @Override public void innerError(Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { if (!veryEnd) { upstream.cancel(); done = true; } active = false; drain(); - } else { - RxJavaPlugins.onError(e); } } @@ -472,11 +463,8 @@ void drain() { } catch (Throwable e) { Exceptions.throwIfFatal(e); upstream.cancel(); - if (errors.addThrowable(e)) { - errors.tryTerminateConsumer(downstream); - } else { - RxJavaPlugins.onError(e); - } + errors.tryAddThrowableOrReport(e); + errors.tryTerminateConsumer(downstream); return; } @@ -496,7 +484,7 @@ void drain() { Exceptions.throwIfFatal(e); upstream.cancel(); - errors.addThrowable(e); + errors.tryAddThrowableOrReport(e); errors.tryTerminateConsumer(downstream); return; } @@ -521,7 +509,7 @@ void drain() { vr = supplier.get(); } catch (Throwable e) { Exceptions.throwIfFatal(e); - errors.addThrowable(e); + errors.tryAddThrowableOrReport(e); if (!veryEnd) { upstream.cancel(); errors.tryTerminateConsumer(downstream); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMapEager.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMapEager.java index 71f01437cd..29c2077226 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMapEager.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMapEager.java @@ -26,7 +26,6 @@ import io.reactivex.rxjava3.internal.subscribers.*; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class FlowableConcatMapEager extends AbstractFlowableWithUpstream { @@ -142,11 +141,9 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -209,14 +206,12 @@ public void innerNext(InnerQueuedSubscriber inner, R value) { @Override public void innerError(InnerQueuedSubscriber inner, Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { inner.setDone(); if (errorMode != ErrorMode.END) { upstream.cancel(); } drain(); - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMapScheduler.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMapScheduler.java index 41cda15f89..828bb5a5fa 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMapScheduler.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableConcatMapScheduler.java @@ -25,7 +25,6 @@ import io.reactivex.rxjava3.internal.queue.SpscArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class FlowableConcatMapScheduler extends AbstractFlowableWithUpstream { @@ -195,15 +194,13 @@ void subscribeActual() { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { inner.cancel(); if (getAndIncrement() == 0) { errors.tryTerminateConsumer(downstream); worker.dispose(); } - } else { - RxJavaPlugins.onError(t); } } @@ -221,15 +218,13 @@ public void innerNext(R value) { @Override public void innerError(Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { upstream.cancel(); if (getAndIncrement() == 0) { errors.tryTerminateConsumer(downstream); worker.dispose(); } - } else { - RxJavaPlugins.onError(e); } } @@ -274,7 +269,7 @@ public void run() { } catch (Throwable e) { Exceptions.throwIfFatal(e); upstream.cancel(); - errors.addThrowable(e); + errors.tryAddThrowableOrReport(e); errors.tryTerminateConsumer(downstream); worker.dispose(); return; @@ -297,7 +292,7 @@ public void run() { Exceptions.throwIfFatal(e); upstream.cancel(); - errors.addThrowable(e); + errors.tryAddThrowableOrReport(e); errors.tryTerminateConsumer(downstream); worker.dispose(); return; @@ -324,7 +319,7 @@ public void run() { } catch (Throwable e) { Exceptions.throwIfFatal(e); upstream.cancel(); - errors.addThrowable(e); + errors.tryAddThrowableOrReport(e); errors.tryTerminateConsumer(downstream); worker.dispose(); return; @@ -386,11 +381,9 @@ void subscribeActual() { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { done = true; schedule(); - } else { - RxJavaPlugins.onError(t); } } @@ -401,15 +394,13 @@ public void innerNext(R value) { @Override public void innerError(Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { if (!veryEnd) { upstream.cancel(); done = true; } active = false; schedule(); - } else { - RxJavaPlugins.onError(e); } } @@ -465,7 +456,7 @@ public void run() { } catch (Throwable e) { Exceptions.throwIfFatal(e); upstream.cancel(); - errors.addThrowable(e); + errors.tryAddThrowableOrReport(e); errors.tryTerminateConsumer(downstream); worker.dispose(); return; @@ -488,7 +479,7 @@ public void run() { Exceptions.throwIfFatal(e); upstream.cancel(); - errors.addThrowable(e); + errors.tryAddThrowableOrReport(e); errors.tryTerminateConsumer(downstream); worker.dispose(); return; @@ -514,7 +505,7 @@ public void run() { vr = supplier.get(); } catch (Throwable e) { Exceptions.throwIfFatal(e); - errors.addThrowable(e); + errors.tryAddThrowableOrReport(e); if (!veryEnd) { upstream.cancel(); errors.tryTerminateConsumer(downstream); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableCreate.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableCreate.java index 1ae39ef326..66cbd7409b 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableCreate.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableCreate.java @@ -88,7 +88,7 @@ static final class SerializedEmitter final BaseEmitter emitter; - final AtomicThrowable error; + final AtomicThrowable errors; final SimplePlainQueue queue; @@ -96,7 +96,7 @@ static final class SerializedEmitter SerializedEmitter(BaseEmitter emitter) { this.emitter = emitter; - this.error = new AtomicThrowable(); + this.errors = new AtomicThrowable(); this.queue = new SpscLinkedArrayQueue(16); } @@ -106,7 +106,7 @@ public void onNext(T t) { return; } if (t == null) { - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("onNext called with a null value.")); return; } if (get() == 0 && compareAndSet(0, 1)) { @@ -139,9 +139,9 @@ public boolean tryOnError(Throwable t) { return false; } if (t == null) { - t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + t = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } - if (error.addThrowable(t)) { + if (errors.tryAddThrowable(t)) { done = true; drain(); return true; @@ -167,7 +167,7 @@ void drain() { void drainLoop() { BaseEmitter e = emitter; SimplePlainQueue q = queue; - AtomicThrowable error = this.error; + AtomicThrowable errors = this.errors; int missed = 1; for (;;) { @@ -177,9 +177,9 @@ void drainLoop() { return; } - if (error.get() != null) { + if (errors.get() != null) { q.clear(); - e.onError(error.terminate()); + errors.tryTerminateConsumer(e); return; } @@ -255,10 +255,10 @@ abstract static class BaseEmitter @Override public void onComplete() { - complete(); + completeDownstream(); } - protected void complete() { + protected void completeDownstream() { if (isCancelled()) { return; } @@ -271,20 +271,27 @@ protected void complete() { @Override public final void onError(Throwable e) { - if (!tryOnError(e)) { + if (e == null) { + e = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); + } + if (!signalError(e)) { RxJavaPlugins.onError(e); } } @Override - public boolean tryOnError(Throwable e) { - return error(e); - } - - protected boolean error(Throwable e) { + public final boolean tryOnError(Throwable e) { if (e == null) { - e = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + e = ExceptionHelper.createNullPointerException("tryOnError called with a null Throwable."); } + return signalError(e); + } + + public boolean signalError(Throwable e) { + return errorDownstream(e); + } + + protected boolean errorDownstream(Throwable e) { if (isCancelled()) { return false; } @@ -366,7 +373,7 @@ public void onNext(T t) { if (t != null) { downstream.onNext(t); } else { - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("onNext called with a null value.")); return; } @@ -395,7 +402,7 @@ public final void onNext(T t) { } if (t == null) { - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("onNext called with a null value.")); return; } @@ -464,7 +471,7 @@ public void onNext(T t) { } if (t == null) { - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("onNext called with a null value.")); return; } queue.offer(t); @@ -472,15 +479,11 @@ public void onNext(T t) { } @Override - public boolean tryOnError(Throwable e) { + public boolean signalError(Throwable e) { if (done || isCancelled()) { return false; } - if (e == null) { - e = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); - } - error = e; done = true; drain(); @@ -533,9 +536,9 @@ void drain() { if (d && empty) { Throwable ex = error; if (ex != null) { - error(ex); + errorDownstream(ex); } else { - complete(); + completeDownstream(); } return; } @@ -562,9 +565,9 @@ void drain() { if (d && empty) { Throwable ex = error; if (ex != null) { - error(ex); + errorDownstream(ex); } else { - complete(); + completeDownstream(); } return; } @@ -606,7 +609,7 @@ public void onNext(T t) { } if (t == null) { - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("onNext called with a null value.")); return; } queue.set(t); @@ -614,13 +617,10 @@ public void onNext(T t) { } @Override - public boolean tryOnError(Throwable e) { + public boolean signalError(Throwable e) { if (done || isCancelled()) { return false; } - if (e == null) { - onError(new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.")); - } error = e; done = true; drain(); @@ -673,9 +673,9 @@ void drain() { if (d && empty) { Throwable ex = error; if (ex != null) { - error(ex); + errorDownstream(ex); } else { - complete(); + completeDownstream(); } return; } @@ -702,9 +702,9 @@ void drain() { if (d && empty) { Throwable ex = error; if (ex != null) { - error(ex); + errorDownstream(ex); } else { - complete(); + completeDownstream(); } return; } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableDistinct.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableDistinct.java index 08e1060cc2..870710bd87 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableDistinct.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableDistinct.java @@ -25,6 +25,7 @@ import io.reactivex.rxjava3.internal.fuseable.QueueFuseable; import io.reactivex.rxjava3.internal.subscribers.BasicFuseableSubscriber; import io.reactivex.rxjava3.internal.subscriptions.EmptySubscription; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class FlowableDistinct extends AbstractFlowableWithUpstream { @@ -44,7 +45,7 @@ protected void subscribeActual(Subscriber subscriber) { Collection collection; try { - collection = ObjectHelper.requireNonNull(collectionSupplier.get(), "The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + collection = ExceptionHelper.nullCheck(collectionSupplier.get(), "The collectionSupplier returned a null Collection."); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); EmptySubscription.error(ex, subscriber); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableError.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableError.java index cfb0a59ab3..f65410ff11 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableError.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableError.java @@ -18,8 +18,8 @@ import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Supplier; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.subscriptions.EmptySubscription; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; public final class FlowableError extends Flowable { final Supplier errorSupplier; @@ -31,7 +31,7 @@ public FlowableError(Supplier errorSupplier) { public void subscribeActual(Subscriber s) { Throwable error; try { - error = ObjectHelper.requireNonNull(errorSupplier.get(), "Callable returned null throwable. Null values are generally not allowed in 2.x operators and sources."); + error = ExceptionHelper.nullCheck(errorSupplier.get(), "Callable returned a null Throwable."); } catch (Throwable t) { Exceptions.throwIfFatal(t); error = t; diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMap.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMap.java index 281339c5c0..de53c5d5b8 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMap.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMap.java @@ -142,7 +142,7 @@ public void onNext(T t) { u = ((Supplier)p).get(); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); drain(); return; } @@ -319,11 +319,9 @@ public void onError(Throwable t) { RxJavaPlugins.onError(t); return; } - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -474,7 +472,7 @@ void drainLoop() { } catch (Throwable ex) { Exceptions.throwIfFatal(ex); is.dispose(); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); if (!delayErrors) { upstream.cancel(); } @@ -581,7 +579,7 @@ void disposeAll() { } void innerError(InnerSubscriber inner, Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { inner.done = true; if (!delayErrors) { upstream.cancel(); @@ -590,8 +588,6 @@ void innerError(InnerSubscriber inner, Throwable t) { } } drain(); - } else { - RxJavaPlugins.onError(t); } } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapCompletable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapCompletable.java index cb212f88b2..5c20e9d75a 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapCompletable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapCompletable.java @@ -26,7 +26,6 @@ import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.subscriptions.*; import io.reactivex.rxjava3.internal.util.AtomicThrowable; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps a sequence of values into CompletableSources and awaits their termination. @@ -126,7 +125,7 @@ public void onNext(T value) { @Override public void onError(Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { if (delayErrors) { if (decrementAndGet() == 0) { errors.tryTerminateConsumer(downstream); @@ -143,8 +142,6 @@ public void onError(Throwable e) { errors.tryTerminateConsumer(downstream); } } - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapCompletableCompletable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapCompletableCompletable.java index dd383052de..52a719ca44 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapCompletableCompletable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapCompletableCompletable.java @@ -133,7 +133,7 @@ public void onNext(T value) { @Override public void onError(Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { if (delayErrors) { if (decrementAndGet() == 0) { errors.tryTerminateConsumer(downstream); @@ -150,8 +150,6 @@ public void onError(Throwable e) { errors.tryTerminateConsumer(downstream); } } - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapMaybe.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapMaybe.java index 10b4b48978..f6cb69c84a 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapMaybe.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapMaybe.java @@ -26,7 +26,6 @@ import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps upstream values into MaybeSources and merges their signals into one sequence. @@ -136,13 +135,11 @@ public void onNext(T t) { @Override public void onError(Throwable t) { active.decrementAndGet(); - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (!delayErrors) { set.dispose(); } drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -222,7 +219,7 @@ SpscLinkedArrayQueue getOrCreateQueue() { void innerError(InnerObserver inner, Throwable e) { set.delete(inner); - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { if (!delayErrors) { upstream.cancel(); set.dispose(); @@ -233,8 +230,6 @@ void innerError(InnerObserver inner, Throwable e) { } active.decrementAndGet(); drain(); - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapSingle.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapSingle.java index 0ab30f15f8..b1ba1fed12 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapSingle.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFlatMapSingle.java @@ -26,7 +26,6 @@ import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps upstream values into SingleSources and merges their signals into one sequence. @@ -136,13 +135,11 @@ public void onNext(T t) { @Override public void onError(Throwable t) { active.decrementAndGet(); - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (!delayErrors) { set.dispose(); } drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -222,7 +219,7 @@ SpscLinkedArrayQueue getOrCreateQueue() { void innerError(InnerObserver inner, Throwable e) { set.delete(inner); - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { if (!delayErrors) { upstream.cancel(); set.dispose(); @@ -233,8 +230,6 @@ void innerError(InnerObserver inner, Throwable e) { } active.decrementAndGet(); drain(); - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFromFuture.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFromFuture.java index 7a814dafb2..8356c92915 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFromFuture.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableFromFuture.java @@ -20,6 +20,7 @@ import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.internal.subscriptions.DeferredScalarSubscription; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; public final class FlowableFromFuture extends Flowable { final Future future; @@ -48,7 +49,7 @@ public void subscribeActual(Subscriber s) { return; } if (v == null) { - s.onError(new NullPointerException("The future returned null")); + s.onError(ExceptionHelper.createNullPointerException("The future returned a null value.")); } else { deferred.complete(v); } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGenerate.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGenerate.java index 1370d2fa8a..893ec19ff9 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGenerate.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGenerate.java @@ -21,7 +21,7 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.*; import io.reactivex.rxjava3.internal.subscriptions.*; -import io.reactivex.rxjava3.internal.util.BackpressureHelper; +import io.reactivex.rxjava3.internal.util.*; import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class FlowableGenerate extends Flowable { @@ -167,7 +167,7 @@ public void onNext(T t) { onError(new IllegalStateException("onNext already called in this generate turn")); } else { if (t == null) { - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("onNext called with a null value.")); } else { hasNext = true; downstream.onNext(t); @@ -182,7 +182,7 @@ public void onError(Throwable t) { RxJavaPlugins.onError(t); } else { if (t == null) { - t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + t = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } terminate = true; downstream.onError(t); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGroupBy.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGroupBy.java index 9da6e208b6..41643e0528 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGroupBy.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGroupBy.java @@ -24,7 +24,6 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.flowables.GroupedFlowable; import io.reactivex.rxjava3.functions.*; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.*; import io.reactivex.rxjava3.internal.util.*; @@ -165,7 +164,7 @@ public void onNext(T t) { V v; try { - v = ObjectHelper.requireNonNull(valueSelector.apply(t), "The valueSelector returned null"); + v = ExceptionHelper.nullCheck(valueSelector.apply(t), "The valueSelector returned a null value."); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); upstream.cancel(); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableMergeWithMaybe.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableMergeWithMaybe.java index 49aa387dde..4ad7f92d07 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableMergeWithMaybe.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableMergeWithMaybe.java @@ -24,7 +24,6 @@ import io.reactivex.rxjava3.internal.queue.SpscArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Merges an Observable and a Maybe by emitting the items of the Observable and the success @@ -142,11 +141,9 @@ public void onNext(T t) { @Override public void onError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { DisposableHelper.dispose(otherObserver); drain(); - } else { - RxJavaPlugins.onError(ex); } } @@ -200,11 +197,9 @@ void otherSuccess(T value) { } void otherError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { SubscriptionHelper.cancel(mainSubscription); drain(); - } else { - RxJavaPlugins.onError(ex); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableMergeWithSingle.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableMergeWithSingle.java index 9a2337c40f..33fe6b8454 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableMergeWithSingle.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableMergeWithSingle.java @@ -24,7 +24,6 @@ import io.reactivex.rxjava3.internal.queue.SpscArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Merges an Observable and a Maybe by emitting the items of the Observable and the success @@ -142,11 +141,9 @@ public void onNext(T t) { @Override public void onError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { DisposableHelper.dispose(otherObserver); drain(); - } else { - RxJavaPlugins.onError(ex); } } @@ -200,11 +197,9 @@ void otherSuccess(T value) { } void otherError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { SubscriptionHelper.cancel(mainSubscription); drain(); - } else { - RxJavaPlugins.onError(ex); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableReplay.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableReplay.java index 7b1009137a..8d9e2e8460 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableReplay.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableReplay.java @@ -24,7 +24,6 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.flowables.ConnectableFlowable; import io.reactivex.rxjava3.functions.*; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.fuseable.HasUpstreamPublisher; import io.reactivex.rxjava3.internal.subscribers.SubscriberResourceWrapper; import io.reactivex.rxjava3.internal.subscriptions.*; @@ -1112,7 +1111,7 @@ static final class MulticastFlowable extends Flowable { protected void subscribeActual(Subscriber child) { ConnectableFlowable cf; try { - cf = ObjectHelper.requireNonNull(connectableFactory.get(), "The connectableFactory returned null"); + cf = ExceptionHelper.nullCheck(connectableFactory.get(), "The connectableFactory returned a null ConnectableFlowable."); } catch (Throwable e) { Exceptions.throwIfFatal(e); EmptySubscription.error(e, child); @@ -1121,7 +1120,7 @@ protected void subscribeActual(Subscriber child) { Publisher observable; try { - observable = ObjectHelper.requireNonNull(selector.apply(cf), "The selector returned a null Publisher"); + observable = ExceptionHelper.nullCheck(selector.apply(cf), "The selector returned a null Publisher."); } catch (Throwable e) { Exceptions.throwIfFatal(e); EmptySubscription.error(e, child); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSequenceEqual.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSequenceEqual.java index 0c825c9ded..05be9542be 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSequenceEqual.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSequenceEqual.java @@ -24,7 +24,6 @@ import io.reactivex.rxjava3.internal.queue.SpscArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.*; import io.reactivex.rxjava3.internal.util.AtomicThrowable; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class FlowableSequenceEqual extends Flowable { final Publisher first; @@ -146,11 +145,8 @@ public void drain() { } catch (Throwable exc) { Exceptions.throwIfFatal(exc); cancelAndClear(); - if (errors.addThrowable(exc)) { - errors.tryTerminateConsumer(downstream); - } else { - RxJavaPlugins.onError(exc); - } + errors.tryAddThrowableOrReport(exc); + errors.tryTerminateConsumer(downstream); return; } v1 = a; @@ -165,11 +161,8 @@ public void drain() { } catch (Throwable exc) { Exceptions.throwIfFatal(exc); cancelAndClear(); - if (errors.addThrowable(exc)) { - errors.tryTerminateConsumer(downstream); - } else { - RxJavaPlugins.onError(exc); - } + errors.tryAddThrowableOrReport(exc); + errors.tryTerminateConsumer(downstream); return; } v2 = b; @@ -198,7 +191,7 @@ public void drain() { } catch (Throwable exc) { Exceptions.throwIfFatal(exc); cancelAndClear(); - errors.addThrowable(exc); + errors.tryAddThrowableOrReport(exc); errors.tryTerminateConsumer(downstream); return; } @@ -241,10 +234,8 @@ public void drain() { @Override public void innerError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { drain(); - } else { - RxJavaPlugins.onError(t); } } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSequenceEqualSingle.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSequenceEqualSingle.java index b43377dd06..7761c93041 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSequenceEqualSingle.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSequenceEqualSingle.java @@ -146,11 +146,8 @@ public void drain() { } catch (Throwable exc) { Exceptions.throwIfFatal(exc); cancelAndClear(); - if (errors.addThrowable(exc)) { - errors.tryTerminateConsumer(downstream); - } else { - RxJavaPlugins.onError(exc); - } + errors.tryAddThrowableOrReport(exc); + errors.tryTerminateConsumer(downstream); return; } v1 = a; @@ -165,11 +162,8 @@ public void drain() { } catch (Throwable exc) { Exceptions.throwIfFatal(exc); cancelAndClear(); - if (errors.addThrowable(exc)) { - errors.tryTerminateConsumer(downstream); - } else { - RxJavaPlugins.onError(exc); - } + errors.tryAddThrowableOrReport(exc); + errors.tryTerminateConsumer(downstream); return; } v2 = b; @@ -198,7 +192,7 @@ public void drain() { } catch (Throwable exc) { Exceptions.throwIfFatal(exc); cancelAndClear(); - errors.addThrowable(exc); + errors.tryAddThrowableOrReport(exc); errors.tryTerminateConsumer(downstream); return; } @@ -241,10 +235,8 @@ public void drain() { @Override public void innerError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { drain(); - } else { - RxJavaPlugins.onError(t); } } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSwitchMap.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSwitchMap.java index e146117c1d..e77110b6a0 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSwitchMap.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableSwitchMap.java @@ -134,7 +134,7 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (!done && errors.addThrowable(t)) { + if (!done && errors.tryAddThrowable(t)) { if (!delayErrors) { disposeInner(); } @@ -265,7 +265,7 @@ void drain() { } catch (Throwable ex) { Exceptions.throwIfFatal(ex); inner.cancel(); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); d = true; v = null; } @@ -392,7 +392,7 @@ public void onNext(R t) { @Override public void onError(Throwable t) { SwitchMapSubscriber p = parent; - if (index == p.unique && p.errors.addThrowable(t)) { + if (index == p.unique && p.errors.tryAddThrowable(t)) { if (!p.delayErrors) { p.upstream.cancel(); p.done = true; diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToList.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToList.java index da395c09d2..439fba1074 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToList.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToList.java @@ -20,8 +20,8 @@ import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Supplier; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.subscriptions.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; public final class FlowableToList> extends AbstractFlowableWithUpstream { final Supplier collectionSupplier; @@ -35,7 +35,7 @@ public FlowableToList(Flowable source, Supplier collectionSupplier) { protected void subscribeActual(Subscriber s) { U coll; try { - coll = ObjectHelper.requireNonNull(collectionSupplier.get(), "The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + coll = ExceptionHelper.nullCheck(collectionSupplier.get(), "The collectionSupplier returned a null Collection."); } catch (Throwable e) { Exceptions.throwIfFatal(e); EmptySubscription.error(e, s); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToListSingle.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToListSingle.java index dd5aac30e1..b90869ad62 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToListSingle.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToListSingle.java @@ -22,10 +22,9 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Supplier; import io.reactivex.rxjava3.internal.disposables.EmptyDisposable; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.fuseable.FuseToFlowable; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; -import io.reactivex.rxjava3.internal.util.ArrayListSupplier; +import io.reactivex.rxjava3.internal.util.*; import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class FlowableToListSingle> extends Single implements FuseToFlowable { @@ -48,7 +47,7 @@ public FlowableToListSingle(Flowable source, Supplier collectionSupplier) protected void subscribeActual(SingleObserver observer) { U coll; try { - coll = ObjectHelper.requireNonNull(collectionSupplier.get(), "The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + coll = ExceptionHelper.nullCheck(collectionSupplier.get(), "The collectionSupplier returned a null Collection."); } catch (Throwable e) { Exceptions.throwIfFatal(e); EmptyDisposable.error(e, observer); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableWindowBoundary.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableWindowBoundary.java index e6f70107da..ba43da6d84 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableWindowBoundary.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableWindowBoundary.java @@ -107,11 +107,9 @@ public void onNext(T t) { @Override public void onError(Throwable e) { boundarySubscriber.dispose(); - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { done = true; drain(); - } else { - RxJavaPlugins.onError(e); } } @@ -151,11 +149,9 @@ void innerNext() { void innerError(Throwable e) { SubscriptionHelper.cancel(upstream); - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { done = true; drain(); - } else { - RxJavaPlugins.onError(e); } } @@ -248,7 +244,7 @@ void drain() { } else { SubscriptionHelper.cancel(upstream); boundarySubscriber.dispose(); - errors.addThrowable(new MissingBackpressureException("Could not deliver a window due to lack of requests")); + errors.tryAddThrowableOrReport(new MissingBackpressureException("Could not deliver a window due to lack of requests")); done = true; } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableZip.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableZip.java index 0d080330a9..09f1a59a7f 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableZip.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableZip.java @@ -26,7 +26,6 @@ import io.reactivex.rxjava3.internal.queue.SpscArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.*; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class FlowableZip extends Flowable { @@ -145,11 +144,9 @@ public void cancel() { } void error(ZipSubscriber inner, Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { inner.done = true; drain(); - } else { - RxJavaPlugins.onError(e); } } @@ -185,7 +182,7 @@ void drain() { if (!delayErrors && errors.get() != null) { cancelAll(); - a.onError(errors.terminate()); + errors.tryTerminateConsumer(a); return; } @@ -203,12 +200,7 @@ void drain() { boolean sourceEmpty = v == null; if (d && sourceEmpty) { cancelAll(); - Throwable ex = errors.get(); - if (ex != null) { - a.onError(errors.terminate()); - } else { - a.onComplete(); - } + errors.tryTerminateConsumer(a); return; } if (!sourceEmpty) { @@ -219,10 +211,10 @@ void drain() { } catch (Throwable ex) { Exceptions.throwIfFatal(ex); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); if (!delayErrors) { cancelAll(); - a.onError(errors.terminate()); + errors.tryTerminateConsumer(a); return; } empty = true; @@ -241,8 +233,8 @@ void drain() { } catch (Throwable ex) { Exceptions.throwIfFatal(ex); cancelAll(); - errors.addThrowable(ex); - a.onError(errors.terminate()); + errors.tryAddThrowableOrReport(ex); + errors.tryTerminateConsumer(a); return; } @@ -260,7 +252,7 @@ void drain() { if (!delayErrors && errors.get() != null) { cancelAll(); - a.onError(errors.terminate()); + errors.tryTerminateConsumer(a); return; } @@ -275,12 +267,7 @@ void drain() { boolean empty = v == null; if (d && empty) { cancelAll(); - Throwable ex = errors.get(); - if (ex != null) { - a.onError(errors.terminate()); - } else { - a.onComplete(); - } + errors.tryTerminateConsumer(a); return; } if (!empty) { @@ -288,10 +275,10 @@ void drain() { } } catch (Throwable ex) { Exceptions.throwIfFatal(ex); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); if (!delayErrors) { cancelAll(); - a.onError(errors.terminate()); + errors.tryTerminateConsumer(a); return; } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeConcatArrayDelayError.java b/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeConcatArrayDelayError.java index 2e04f7c733..a928db62a6 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeConcatArrayDelayError.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeConcatArrayDelayError.java @@ -22,7 +22,6 @@ import io.reactivex.rxjava3.internal.disposables.SequentialDisposable; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Concatenate values of each MaybeSource provided in an array and delays @@ -104,10 +103,8 @@ public void onSuccess(T value) { @Override public void onError(Throwable e) { current.lazySet(NotificationLite.COMPLETE); - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { drain(); - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeCreate.java b/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeCreate.java index bfa6a9444e..2fc0f48414 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeCreate.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeCreate.java @@ -20,6 +20,7 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Cancellable; import io.reactivex.rxjava3.internal.disposables.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -68,7 +69,7 @@ public void onSuccess(T value) { if (d != DisposableHelper.DISPOSED) { try { if (value == null) { - downstream.onError(new NullPointerException("onSuccess called with null. Null values are generally not allowed in 2.x operators and sources.")); + downstream.onError(ExceptionHelper.createNullPointerException("onSuccess called with a null value.")); } else { downstream.onSuccess(value); } @@ -91,7 +92,7 @@ public void onError(Throwable t) { @Override public boolean tryOnError(Throwable t) { if (t == null) { - t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + t = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } if (get() != DisposableHelper.DISPOSED) { Disposable d = getAndSet(DisposableHelper.DISPOSED); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeErrorCallable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeErrorCallable.java index f60e749700..f3b631ba36 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeErrorCallable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeErrorCallable.java @@ -17,7 +17,7 @@ import io.reactivex.rxjava3.disposables.Disposables; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Supplier; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; /** * Signals a Throwable returned by a Supplier. @@ -38,7 +38,7 @@ protected void subscribeActual(MaybeObserver observer) { Throwable ex; try { - ex = ObjectHelper.requireNonNull(errorSupplier.get(), "Supplier returned null throwable. Null values are generally not allowed in 2.x operators and sources."); + ex = ExceptionHelper.nullCheck(errorSupplier.get(), "Supplier returned a null Throwable."); } catch (Throwable ex1) { Exceptions.throwIfFatal(ex1); ex = ex1; diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeMergeArray.java b/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeMergeArray.java index 53c4e18cf3..d5e5069d22 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeMergeArray.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeMergeArray.java @@ -25,7 +25,6 @@ import io.reactivex.rxjava3.internal.fuseable.SimpleQueue; import io.reactivex.rxjava3.internal.subscriptions.*; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Run all MaybeSources of an array at once and signal their values as they become available. @@ -56,7 +55,7 @@ protected void subscribeActual(Subscriber s) { s.onSubscribe(parent); - AtomicThrowable e = parent.error; + AtomicThrowable e = parent.errors; for (MaybeSource source : maybes) { if (parent.isCancelled() || e.get() != null) { @@ -80,7 +79,7 @@ static final class MergeMaybeObserver final SimpleQueueWithConsumerIndex queue; - final AtomicThrowable error; + final AtomicThrowable errors; final int sourceCount; @@ -95,7 +94,7 @@ static final class MergeMaybeObserver this.sourceCount = sourceCount; this.set = new CompositeDisposable(); this.requested = new AtomicLong(); - this.error = new AtomicThrowable(); + this.errors = new AtomicThrowable(); this.queue = queue; } @@ -162,12 +161,10 @@ public void onSuccess(T value) { @Override public void onError(Throwable e) { - if (error.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { set.dispose(); queue.offer(NotificationLite.COMPLETE); drain(); - } else { - RxJavaPlugins.onError(e); } } @@ -198,10 +195,10 @@ void drainNormal() { return; } - Throwable ex = error.get(); + Throwable ex = errors.get(); if (ex != null) { q.clear(); - error.tryTerminateConsumer(downstream); + errors.tryTerminateConsumer(downstream); return; } @@ -224,10 +221,10 @@ void drainNormal() { } if (e == r) { - Throwable ex = error.get(); + Throwable ex = errors.get(); if (ex != null) { q.clear(); - error.tryTerminateConsumer(downstream); + errors.tryTerminateConsumer(downstream); return; } @@ -260,7 +257,7 @@ void drainFused() { q.clear(); return; } - Throwable ex = error.get(); + Throwable ex = errors.get(); if (ex != null) { q.clear(); a.onError(ex); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapCompletable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapCompletable.java index a37bba09dd..6e16c9b6a9 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapCompletable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapCompletable.java @@ -27,7 +27,6 @@ import io.reactivex.rxjava3.internal.queue.SpscArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps the upstream items into {@link CompletableSource}s and subscribes to them one after the @@ -124,7 +123,7 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (errorMode == ErrorMode.IMMEDIATE) { inner.dispose(); errors.tryTerminateConsumer(downstream); @@ -135,8 +134,6 @@ public void onError(Throwable t) { done = true; drain(); } - } else { - RxJavaPlugins.onError(t); } } @@ -163,7 +160,7 @@ public boolean isDisposed() { } void innerError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { if (errorMode == ErrorMode.IMMEDIATE) { upstream.cancel(); errors.tryTerminateConsumer(downstream); @@ -174,8 +171,6 @@ void innerError(Throwable ex) { active = false; drain(); } - } else { - RxJavaPlugins.onError(ex); } } @@ -233,7 +228,7 @@ void drain() { Exceptions.throwIfFatal(ex); queue.clear(); upstream.cancel(); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); errors.tryTerminateConsumer(downstream); return; } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapMaybe.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapMaybe.java index bfff35cf91..39fa04b174 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapMaybe.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapMaybe.java @@ -27,7 +27,6 @@ import io.reactivex.rxjava3.internal.queue.SpscArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps each upstream item into a {@link MaybeSource}, subscribes to them one after the other terminates @@ -139,14 +138,12 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (errorMode == ErrorMode.IMMEDIATE) { inner.dispose(); } done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -186,14 +183,12 @@ void innerComplete() { } void innerError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { if (errorMode != ErrorMode.END) { upstream.cancel(); } this.state = STATE_INACTIVE; drain(); - } else { - RxJavaPlugins.onError(ex); } } @@ -261,7 +256,7 @@ void drain() { Exceptions.throwIfFatal(ex); upstream.cancel(); queue.clear(); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); errors.tryTerminateConsumer(downstream); return; } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapSingle.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapSingle.java index 918c4a1d73..cd5e857274 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapSingle.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableConcatMapSingle.java @@ -27,7 +27,6 @@ import io.reactivex.rxjava3.internal.queue.SpscArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps each upstream item into a {@link SingleSource}, subscribes to them one after the other terminates @@ -139,14 +138,12 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (errorMode == ErrorMode.IMMEDIATE) { inner.dispose(); } done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -181,14 +178,12 @@ void innerSuccess(R item) { } void innerError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { if (errorMode != ErrorMode.END) { upstream.cancel(); } this.state = STATE_INACTIVE; drain(); - } else { - RxJavaPlugins.onError(ex); } } @@ -256,7 +251,7 @@ void drain() { Exceptions.throwIfFatal(ex); upstream.cancel(); queue.clear(); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); errors.tryTerminateConsumer(downstream); return; } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapCompletable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapCompletable.java index f58eb90688..f354d8f057 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapCompletable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapCompletable.java @@ -123,15 +123,13 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (delayErrors) { onComplete(); } else { disposeInner(); errors.tryTerminateConsumer(downstream); } - } else { - RxJavaPlugins.onError(t); } } @@ -164,7 +162,7 @@ public boolean isDisposed() { void innerError(SwitchMapInnerObserver sender, Throwable error) { if (inner.compareAndSet(sender, null)) { - if (errors.addThrowable(error)) { + if (errors.tryAddThrowableOrReport(error)) { if (delayErrors) { if (done) { errors.tryTerminateConsumer(downstream); @@ -174,10 +172,10 @@ void innerError(SwitchMapInnerObserver sender, Throwable error) { disposeInner(); errors.tryTerminateConsumer(downstream); } - return; } + } else { + RxJavaPlugins.onError(error); } - RxJavaPlugins.onError(error); } void innerComplete(SwitchMapInnerObserver sender) { diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapMaybe.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapMaybe.java index be9d06c66c..56858d5d22 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapMaybe.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapMaybe.java @@ -141,14 +141,12 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (!delayErrors) { disposeInner(); } done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -182,16 +180,16 @@ public void cancel() { void innerError(SwitchMapMaybeObserver sender, Throwable ex) { if (inner.compareAndSet(sender, null)) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { if (!delayErrors) { upstream.cancel(); disposeInner(); } drain(); - return; } + } else { + RxJavaPlugins.onError(ex); } - RxJavaPlugins.onError(ex); } void innerComplete(SwitchMapMaybeObserver sender) { diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapSingle.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapSingle.java index b37ba93b15..ac0880082b 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapSingle.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/FlowableSwitchMapSingle.java @@ -141,14 +141,12 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (!delayErrors) { disposeInner(); } done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -182,16 +180,16 @@ public void cancel() { void innerError(SwitchMapSingleObserver sender, Throwable ex) { if (inner.compareAndSet(sender, null)) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { if (!delayErrors) { upstream.cancel(); disposeInner(); } drain(); - return; } + } else { + RxJavaPlugins.onError(ex); } - RxJavaPlugins.onError(ex); } void drain() { diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapCompletable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapCompletable.java index 993e315df4..4921722b5d 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapCompletable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapCompletable.java @@ -24,7 +24,6 @@ import io.reactivex.rxjava3.internal.fuseable.*; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps the upstream items into {@link CompletableSource}s and subscribes to them one after the @@ -136,7 +135,7 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (errorMode == ErrorMode.IMMEDIATE) { disposed = true; inner.dispose(); @@ -148,8 +147,6 @@ public void onError(Throwable t) { done = true; drain(); } - } else { - RxJavaPlugins.onError(t); } } @@ -176,7 +173,7 @@ public boolean isDisposed() { } void innerError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { if (errorMode == ErrorMode.IMMEDIATE) { disposed = true; upstream.dispose(); @@ -188,8 +185,6 @@ void innerError(Throwable ex) { active = false; drain(); } - } else { - RxJavaPlugins.onError(ex); } } @@ -237,11 +232,8 @@ void drain() { disposed = true; queue.clear(); upstream.dispose(); - if (errors.addThrowable(ex)) { - errors.tryTerminateConsumer(downstream); - } else { - RxJavaPlugins.onError(ex); - } + errors.tryAddThrowableOrReport(ex); + errors.tryTerminateConsumer(downstream); return; } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapMaybe.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapMaybe.java index cba6f9a4e1..17e4de9050 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapMaybe.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapMaybe.java @@ -24,7 +24,6 @@ import io.reactivex.rxjava3.internal.fuseable.SimplePlainQueue; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps each upstream item into a {@link MaybeSource}, subscribes to them one after the other terminates @@ -123,14 +122,12 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (errorMode == ErrorMode.IMMEDIATE) { inner.dispose(); } done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -169,14 +166,12 @@ void innerComplete() { } void innerError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { if (errorMode != ErrorMode.END) { upstream.dispose(); } this.state = STATE_INACTIVE; drain(); - } else { - RxJavaPlugins.onError(ex); } } @@ -234,7 +229,7 @@ void drain() { Exceptions.throwIfFatal(ex); upstream.dispose(); queue.clear(); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); errors.tryTerminateConsumer(downstream); return; } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapSingle.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapSingle.java index 30028d813d..91428a80db 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapSingle.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableConcatMapSingle.java @@ -24,7 +24,6 @@ import io.reactivex.rxjava3.internal.fuseable.SimplePlainQueue; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps each upstream item into a {@link SingleSource}, subscribes to them one after the other terminates @@ -123,14 +122,12 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (errorMode == ErrorMode.IMMEDIATE) { inner.dispose(); } done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -164,14 +161,12 @@ void innerSuccess(R item) { } void innerError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { if (errorMode != ErrorMode.END) { upstream.dispose(); } this.state = STATE_INACTIVE; drain(); - } else { - RxJavaPlugins.onError(ex); } } @@ -229,7 +224,7 @@ void drain() { Exceptions.throwIfFatal(ex); upstream.dispose(); queue.clear(); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); errors.tryTerminateConsumer(downstream); return; } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapCompletable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapCompletable.java index 2b23d4397d..06a09676d0 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapCompletable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapCompletable.java @@ -121,15 +121,13 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (delayErrors) { onComplete(); } else { disposeInner(); errors.tryTerminateConsumer(downstream); } - } else { - RxJavaPlugins.onError(t); } } @@ -162,7 +160,7 @@ public boolean isDisposed() { void innerError(SwitchMapInnerObserver sender, Throwable error) { if (inner.compareAndSet(sender, null)) { - if (errors.addThrowable(error)) { + if (errors.tryAddThrowableOrReport(error)) { if (delayErrors) { if (done) { errors.tryTerminateConsumer(downstream); @@ -172,10 +170,10 @@ void innerError(SwitchMapInnerObserver sender, Throwable error) { disposeInner(); errors.tryTerminateConsumer(downstream); } - return; } + } else { + RxJavaPlugins.onError(error); } - RxJavaPlugins.onError(error); } void innerComplete(SwitchMapInnerObserver sender) { diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapMaybe.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapMaybe.java index 99cc745b5a..b85bc0e2c2 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapMaybe.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapMaybe.java @@ -134,14 +134,12 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (!delayErrors) { disposeInner(); } done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -174,16 +172,16 @@ public boolean isDisposed() { void innerError(SwitchMapMaybeObserver sender, Throwable ex) { if (inner.compareAndSet(sender, null)) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { if (!delayErrors) { upstream.dispose(); disposeInner(); } drain(); - return; } + } else { + RxJavaPlugins.onError(ex); } - RxJavaPlugins.onError(ex); } void innerComplete(SwitchMapMaybeObserver sender) { diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapSingle.java b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapSingle.java index ba7ffa359f..3343f93d97 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapSingle.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/mixed/ObservableSwitchMapSingle.java @@ -134,14 +134,12 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (!delayErrors) { disposeInner(); } done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -174,16 +172,16 @@ public boolean isDisposed() { void innerError(SwitchMapSingleObserver sender, Throwable ex) { if (inner.compareAndSet(sender, null)) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { if (!delayErrors) { upstream.dispose(); disposeInner(); } drain(); - return; } + } else { + RxJavaPlugins.onError(ex); } - RxJavaPlugins.onError(ex); } void drain() { diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableBuffer.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableBuffer.java index 316cf3aa21..d0ae0b89cc 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableBuffer.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableBuffer.java @@ -23,6 +23,7 @@ import io.reactivex.rxjava3.functions.Supplier; import io.reactivex.rxjava3.internal.disposables.*; import io.reactivex.rxjava3.internal.functions.ObjectHelper; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; public final class ObservableBuffer> extends AbstractObservableWithUpstream { final int count; @@ -184,7 +185,7 @@ public void onNext(T t) { U b; try { - b = ObjectHelper.requireNonNull(bufferSupplier.get(), "The bufferSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + b = ExceptionHelper.nullCheck(bufferSupplier.get(), "The bufferSupplier returned a null Collection."); } catch (Throwable e) { buffers.clear(); upstream.dispose(); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableBufferBoundary.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableBufferBoundary.java index 63677b1a18..961c6cd374 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableBufferBoundary.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableBufferBoundary.java @@ -122,15 +122,13 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { observers.dispose(); synchronized (this) { buffers = null; } done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -252,8 +250,7 @@ void drain() { boolean d = done; if (d && errors.get() != null) { q.clear(); - Throwable ex = errors.terminate(); - a.onError(ex); + errors.tryTerminateConsumer(a); return; } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableCombineLatest.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableCombineLatest.java index 6831cb3e9e..ac18b94d79 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableCombineLatest.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableCombineLatest.java @@ -23,7 +23,6 @@ import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.util.AtomicThrowable; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class ObservableCombineLatest extends Observable { final ObservableSource[] sources; @@ -168,7 +167,7 @@ void drain() { if (!delayError && errors.get() != null) { cancelSources(); clear(q); - a.onError(errors.terminate()); + errors.tryTerminateConsumer(a); return; } @@ -178,12 +177,7 @@ void drain() { if (d && empty) { clear(q); - Throwable ex = errors.terminate(); - if (ex == null) { - a.onComplete(); - } else { - a.onError(ex); - } + errors.tryTerminateConsumer(a); return; } @@ -197,11 +191,10 @@ void drain() { v = ObjectHelper.requireNonNull(combiner.apply(s), "The combiner returned a null value"); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); cancelSources(); clear(q); - ex = errors.terminate(); - a.onError(ex); + errors.tryTerminateConsumer(a); return; } @@ -239,7 +232,7 @@ void innerNext(int index, T item) { } void innerError(int index, Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { boolean cancelOthers = true; if (delayError) { synchronized (this) { @@ -258,8 +251,6 @@ void innerError(int index, Throwable ex) { cancelSources(); } drain(); - } else { - RxJavaPlugins.onError(ex); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMap.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMap.java index 6707d38f2b..665306db95 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMap.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMap.java @@ -354,11 +354,9 @@ public void onNext(T value) { @Override public void onError(Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { done = true; drain(); - } else { - RxJavaPlugins.onError(e); } } @@ -420,11 +418,8 @@ void drain() { Exceptions.throwIfFatal(ex); cancelled = true; this.upstream.dispose(); - if (errors.addThrowable(ex)) { - errors.tryTerminateConsumer(downstream); - } else { - RxJavaPlugins.onError(ex); - } + errors.tryAddThrowableOrReport(ex); + errors.tryTerminateConsumer(downstream); return; } @@ -447,11 +442,8 @@ void drain() { cancelled = true; this.upstream.dispose(); queue.clear(); - if (errors.addThrowable(ex)) { - errors.tryTerminateConsumer(downstream); - } else { - RxJavaPlugins.onError(ex); - } + errors.tryAddThrowableOrReport(ex); + errors.tryTerminateConsumer(downstream); return; } @@ -462,7 +454,7 @@ void drain() { w = ((Supplier)o).get(); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); continue; } @@ -509,14 +501,12 @@ public void onNext(R value) { @Override public void onError(Throwable e) { ConcatMapDelayErrorObserver p = parent; - if (p.errors.addThrowable(e)) { + if (p.errors.tryAddThrowableOrReport(e)) { if (!p.tillTheEnd) { p.upstream.dispose(); } p.active = false; p.drain(); - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMapEager.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMapEager.java index 132ed90682..47c4099b83 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMapEager.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMapEager.java @@ -26,7 +26,6 @@ import io.reactivex.rxjava3.internal.observers.*; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.util.*; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class ObservableConcatMapEager extends AbstractObservableWithUpstream { @@ -146,11 +145,9 @@ public void onNext(T value) { @Override public void onError(Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { done = true; drain(); - } else { - RxJavaPlugins.onError(e); } } @@ -213,14 +210,12 @@ public void innerNext(InnerQueuedObserver inner, R value) { @Override public void innerError(InnerQueuedObserver inner, Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { if (errorMode == ErrorMode.IMMEDIATE) { upstream.dispose(); } inner.setDone(); drain(); - } else { - RxJavaPlugins.onError(e); } } @@ -282,11 +277,8 @@ public void drain() { upstream.dispose(); q.clear(); disposeAll(); - if (errors.addThrowable(ex)) { - errors.tryTerminateConsumer(downstream); - } else { - RxJavaPlugins.onError(ex); - } + errors.tryAddThrowableOrReport(ex); + errors.tryTerminateConsumer(downstream); return; } @@ -385,7 +377,7 @@ public void drain() { w = aq.poll(); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); current = null; activeCount--; diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMapScheduler.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMapScheduler.java index 70b115dabb..efe4b79fc6 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMapScheduler.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableConcatMapScheduler.java @@ -368,11 +368,9 @@ public void onNext(T value) { @Override public void onError(Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { done = true; drain(); - } else { - RxJavaPlugins.onError(e); } } @@ -441,11 +439,8 @@ public void run() { Exceptions.throwIfFatal(ex); cancelled = true; this.upstream.dispose(); - if (errors.addThrowable(ex)) { - errors.tryTerminateConsumer(downstream); - } else { - RxJavaPlugins.onError(ex); - } + errors.tryAddThrowableOrReport(ex); + errors.tryTerminateConsumer(downstream); worker.dispose(); return; } @@ -470,11 +465,8 @@ public void run() { cancelled = true; this.upstream.dispose(); queue.clear(); - if (errors.addThrowable(ex)) { - errors.tryTerminateConsumer(downstream); - } else { - RxJavaPlugins.onError(ex); - } + errors.tryAddThrowableOrReport(ex); + errors.tryTerminateConsumer(downstream); worker.dispose(); return; } @@ -486,7 +478,7 @@ public void run() { w = ((Supplier)o).get(); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); continue; } @@ -533,14 +525,12 @@ public void onNext(R value) { @Override public void onError(Throwable e) { ConcatMapDelayErrorObserver p = parent; - if (p.errors.addThrowable(e)) { + if (p.errors.tryAddThrowableOrReport(e)) { if (!p.tillTheEnd) { p.upstream.dispose(); } p.active = false; p.drain(); - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableCreate.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableCreate.java index 7d44ca2c45..fe1f394ff3 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableCreate.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableCreate.java @@ -21,7 +21,7 @@ import io.reactivex.rxjava3.internal.disposables.*; import io.reactivex.rxjava3.internal.fuseable.SimpleQueue; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; -import io.reactivex.rxjava3.internal.util.AtomicThrowable; +import io.reactivex.rxjava3.internal.util.*; import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class ObservableCreate extends Observable { @@ -59,7 +59,7 @@ static final class CreateEmitter @Override public void onNext(T t) { if (t == null) { - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("onNext called with a null value.")); return; } if (!isDisposed()) { @@ -77,7 +77,7 @@ public void onError(Throwable t) { @Override public boolean tryOnError(Throwable t) { if (t == null) { - t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + t = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } if (!isDisposed()) { try { @@ -145,7 +145,7 @@ static final class SerializedEmitter final ObservableEmitter emitter; - final AtomicThrowable error; + final AtomicThrowable errors; final SpscLinkedArrayQueue queue; @@ -153,7 +153,7 @@ static final class SerializedEmitter SerializedEmitter(ObservableEmitter emitter) { this.emitter = emitter; - this.error = new AtomicThrowable(); + this.errors = new AtomicThrowable(); this.queue = new SpscLinkedArrayQueue(16); } @@ -163,7 +163,7 @@ public void onNext(T t) { return; } if (t == null) { - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("onNext called with a null value.")); return; } if (get() == 0 && compareAndSet(0, 1)) { @@ -196,9 +196,9 @@ public boolean tryOnError(Throwable t) { return false; } if (t == null) { - t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + t = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } - if (error.addThrowable(t)) { + if (errors.tryAddThrowable(t)) { done = true; drain(); return true; @@ -224,7 +224,7 @@ void drain() { void drainLoop() { ObservableEmitter e = emitter; SpscLinkedArrayQueue q = queue; - AtomicThrowable error = this.error; + AtomicThrowable errors = this.errors; int missed = 1; for (;;) { @@ -234,9 +234,9 @@ void drainLoop() { return; } - if (error.get() != null) { + if (errors.get() != null) { q.clear(); - e.onError(error.terminate()); + errors.tryTerminateConsumer(e); return; } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableDistinct.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableDistinct.java index 9274032f12..98c197156c 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableDistinct.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableDistinct.java @@ -22,6 +22,7 @@ import io.reactivex.rxjava3.internal.disposables.EmptyDisposable; import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.observers.BasicFuseableObserver; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class ObservableDistinct extends AbstractObservableWithUpstream { @@ -41,7 +42,7 @@ protected void subscribeActual(Observer observer) { Collection collection; try { - collection = ObjectHelper.requireNonNull(collectionSupplier.get(), "The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + collection = ExceptionHelper.nullCheck(collectionSupplier.get(), "The collectionSupplier returned a null Collection."); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); EmptyDisposable.error(ex, observer); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableError.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableError.java index bbb88b13bc..7481373e7a 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableError.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableError.java @@ -17,7 +17,7 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Supplier; import io.reactivex.rxjava3.internal.disposables.EmptyDisposable; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; public final class ObservableError extends Observable { final Supplier errorSupplier; @@ -29,7 +29,7 @@ public ObservableError(Supplier errorSupplier) { public void subscribeActual(Observer observer) { Throwable error; try { - error = ObjectHelper.requireNonNull(errorSupplier.get(), "Supplier returned null throwable. Null values are generally not allowed in 2.x operators and sources."); + error = ExceptionHelper.nullCheck(errorSupplier.get(), "Supplier returned a null Throwable."); } catch (Throwable t) { Exceptions.throwIfFatal(t); error = t; diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMap.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMap.java index 0d8c124f83..596719176e 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMap.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMap.java @@ -222,7 +222,7 @@ boolean tryEmitScalar(Supplier value) { u = value.get(); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); drain(); return true; } @@ -285,11 +285,9 @@ public void onError(Throwable t) { RxJavaPlugins.onError(t); return; } - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { done = true; drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -407,7 +405,7 @@ void drainLoop() { } catch (Throwable ex) { Exceptions.throwIfFatal(ex); is.dispose(); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); if (checkTerminate()) { return; } @@ -553,14 +551,12 @@ public void onNext(U t) { @Override public void onError(Throwable t) { - if (parent.errors.addThrowable(t)) { + if (parent.errors.tryAddThrowableOrReport(t)) { if (!parent.delayErrors) { parent.disposeAll(); } done = true; parent.drain(); - } else { - RxJavaPlugins.onError(t); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapCompletable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapCompletable.java index a523757277..26f0505a14 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapCompletable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapCompletable.java @@ -24,7 +24,6 @@ import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.observers.BasicIntQueueDisposable; import io.reactivex.rxjava3.internal.util.AtomicThrowable; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps a sequence of values into CompletableSources and awaits their termination. @@ -108,7 +107,7 @@ public void onNext(T value) { @Override public void onError(Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { if (delayErrors) { if (decrementAndGet() == 0) { errors.tryTerminateConsumer(downstream); @@ -121,8 +120,6 @@ public void onError(Throwable e) { errors.tryTerminateConsumer(downstream); } } - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapCompletableCompletable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapCompletableCompletable.java index 5b9cb76ccb..b9a9213769 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapCompletableCompletable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapCompletableCompletable.java @@ -113,7 +113,7 @@ public void onNext(T value) { @Override public void onError(Throwable e) { - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { if (delayErrors) { if (decrementAndGet() == 0) { errors.tryTerminateConsumer(downstream); @@ -126,8 +126,6 @@ public void onError(Throwable e) { errors.tryTerminateConsumer(downstream); } } - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapMaybe.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapMaybe.java index 1cf9d3799f..9e323ec346 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapMaybe.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapMaybe.java @@ -23,7 +23,6 @@ import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.util.AtomicThrowable; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps upstream values into MaybeSources and merges their signals into one sequence. @@ -117,13 +116,11 @@ public void onNext(T t) { @Override public void onError(Throwable t) { active.decrementAndGet(); - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (!delayErrors) { set.dispose(); } drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -189,15 +186,13 @@ SpscLinkedArrayQueue getOrCreateQueue() { void innerError(InnerObserver inner, Throwable e) { set.delete(inner); - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { if (!delayErrors) { upstream.dispose(); set.dispose(); } active.decrementAndGet(); drain(); - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapSingle.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapSingle.java index 507f45ea70..4ca080a73f 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapSingle.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFlatMapSingle.java @@ -23,7 +23,6 @@ import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.util.AtomicThrowable; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Maps upstream values into SingleSources and merges their signals into one sequence. @@ -117,13 +116,11 @@ public void onNext(T t) { @Override public void onError(Throwable t) { active.decrementAndGet(); - if (errors.addThrowable(t)) { + if (errors.tryAddThrowableOrReport(t)) { if (!delayErrors) { set.dispose(); } drain(); - } else { - RxJavaPlugins.onError(t); } } @@ -189,15 +186,13 @@ SpscLinkedArrayQueue getOrCreateQueue() { void innerError(InnerObserver inner, Throwable e) { set.delete(inner); - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { if (!delayErrors) { upstream.dispose(); set.dispose(); } active.decrementAndGet(); drain(); - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromCallable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromCallable.java index 486afaebf2..db08487f81 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromCallable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromCallable.java @@ -18,8 +18,8 @@ import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Supplier; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.observers.DeferredScalarDisposable; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -43,7 +43,7 @@ public void subscribeActual(Observer observer) { } T value; try { - value = ObjectHelper.requireNonNull(callable.call(), "Callable returned null"); + value = ExceptionHelper.nullCheck(callable.call(), "Callable returned a null value."); } catch (Throwable e) { Exceptions.throwIfFatal(e); if (!d.isDisposed()) { @@ -58,6 +58,6 @@ public void subscribeActual(Observer observer) { @Override public T get() throws Throwable { - return ObjectHelper.requireNonNull(callable.call(), "The callable returned a null value"); + return ExceptionHelper.nullCheck(callable.call(), "The Callable returned a null value."); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromFuture.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromFuture.java index b530f8280d..aa9e7da0bb 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromFuture.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromFuture.java @@ -17,8 +17,8 @@ import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.exceptions.Exceptions; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.observers.DeferredScalarDisposable; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; public final class ObservableFromFuture extends Observable { final Future future; @@ -38,7 +38,7 @@ public void subscribeActual(Observer observer) { if (!d.isDisposed()) { T v; try { - v = ObjectHelper.requireNonNull(unit != null ? future.get(timeout, unit) : future.get(), "Future returned null"); + v = ExceptionHelper.nullCheck(unit != null ? future.get(timeout, unit) : future.get(), "Future returned a null value."); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); if (!d.isDisposed()) { diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromSupplier.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromSupplier.java index 63fa39be0e..44b6dbdd00 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromSupplier.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableFromSupplier.java @@ -16,8 +16,8 @@ import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Supplier; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.observers.DeferredScalarDisposable; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -42,7 +42,7 @@ public void subscribeActual(Observer observer) { } T value; try { - value = ObjectHelper.requireNonNull(supplier.get(), "Supplier returned null"); + value = ExceptionHelper.nullCheck(supplier.get(), "Supplier returned a null value."); } catch (Throwable e) { Exceptions.throwIfFatal(e); if (!d.isDisposed()) { @@ -57,6 +57,6 @@ public void subscribeActual(Observer observer) { @Override public T get() throws Throwable { - return ObjectHelper.requireNonNull(supplier.get(), "The supplier returned a null value"); + return ExceptionHelper.nullCheck(supplier.get(), "The supplier returned a null value."); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableGenerate.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableGenerate.java index 9c484e3957..df94a37dbd 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableGenerate.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableGenerate.java @@ -18,6 +18,7 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.*; import io.reactivex.rxjava3.internal.disposables.EmptyDisposable; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class ObservableGenerate extends Observable { @@ -141,7 +142,7 @@ public void onNext(T t) { onError(new IllegalStateException("onNext already called in this generate turn")); } else { if (t == null) { - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("onNext called with a null value.")); } else { hasNext = true; downstream.onNext(t); @@ -156,7 +157,7 @@ public void onError(Throwable t) { RxJavaPlugins.onError(t); } else { if (t == null) { - t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + t = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } terminate = true; downstream.onError(t); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableMergeWithMaybe.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableMergeWithMaybe.java index 3860207f63..d852bff7dd 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableMergeWithMaybe.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableMergeWithMaybe.java @@ -21,7 +21,6 @@ import io.reactivex.rxjava3.internal.fuseable.SimplePlainQueue; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.util.AtomicThrowable; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Merges an Observable and a Maybe by emitting the items of the Observable and the success @@ -105,11 +104,9 @@ public void onNext(T t) { @Override public void onError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { DisposableHelper.dispose(otherObserver); drain(); - } else { - RxJavaPlugins.onError(ex); } } @@ -151,11 +148,9 @@ void otherSuccess(T value) { } void otherError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { DisposableHelper.dispose(mainDisposable); drain(); - } else { - RxJavaPlugins.onError(ex); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableMergeWithSingle.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableMergeWithSingle.java index d2ed340509..30e80cf4de 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableMergeWithSingle.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableMergeWithSingle.java @@ -21,7 +21,6 @@ import io.reactivex.rxjava3.internal.fuseable.SimplePlainQueue; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.util.AtomicThrowable; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Merges an Observable and a Single by emitting the items of the Observable and the success @@ -105,11 +104,9 @@ public void onNext(T t) { @Override public void onError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { DisposableHelper.dispose(otherObserver); drain(); - } else { - RxJavaPlugins.onError(ex); } } @@ -151,11 +148,9 @@ void otherSuccess(T value) { } void otherError(Throwable ex) { - if (errors.addThrowable(ex)) { + if (errors.tryAddThrowableOrReport(ex)) { DisposableHelper.dispose(mainDisposable); drain(); - } else { - RxJavaPlugins.onError(ex); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableSwitchMap.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableSwitchMap.java index 00aa8557dd..d9d50fc032 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableSwitchMap.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableSwitchMap.java @@ -132,7 +132,7 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - if (!done && errors.addThrowable(t)) { + if (!done && errors.tryAddThrowable(t)) { if (!delayErrors) { disposeInner(); } @@ -272,7 +272,7 @@ void drain() { v = q.poll(); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); - errors.addThrowable(ex); + errors.tryAddThrowableOrReport(ex); active.compareAndSet(inner, null); if (!delayErrors) { disposeInner(); @@ -313,7 +313,7 @@ void drain() { } void innerError(SwitchMapInnerObserver inner, Throwable ex) { - if (inner.index == unique && errors.addThrowable(ex)) { + if (inner.index == unique && errors.tryAddThrowable(ex)) { if (!delayErrors) { upstream.dispose(); done = true; diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToList.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToList.java index 2503428e28..9cde3b4033 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToList.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToList.java @@ -20,7 +20,8 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Supplier; import io.reactivex.rxjava3.internal.disposables.*; -import io.reactivex.rxjava3.internal.functions.*; +import io.reactivex.rxjava3.internal.functions.Functions; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; public final class ObservableToList> extends AbstractObservableWithUpstream { @@ -42,7 +43,7 @@ public ObservableToList(ObservableSource source, Supplier collectionSuppli public void subscribeActual(Observer t) { U coll; try { - coll = ObjectHelper.requireNonNull(collectionSupplier.get(), "The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + coll = ExceptionHelper.nullCheck(collectionSupplier.get(), "The collectionSupplier returned a null Collection."); } catch (Throwable e) { Exceptions.throwIfFatal(e); EmptyDisposable.error(e, t); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToListSingle.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToListSingle.java index 31c741a56c..6258313b61 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToListSingle.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToListSingle.java @@ -20,8 +20,9 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Supplier; import io.reactivex.rxjava3.internal.disposables.*; -import io.reactivex.rxjava3.internal.functions.*; +import io.reactivex.rxjava3.internal.functions.Functions; import io.reactivex.rxjava3.internal.fuseable.FuseToObservable; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class ObservableToListSingle> @@ -46,7 +47,7 @@ public ObservableToListSingle(ObservableSource source, Supplier collection public void subscribeActual(SingleObserver t) { U coll; try { - coll = ObjectHelper.requireNonNull(collectionSupplier.get(), "The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + coll = ExceptionHelper.nullCheck(collectionSupplier.get(), "The collectionSupplier returned a null Collection."); } catch (Throwable e) { Exceptions.throwIfFatal(e); EmptyDisposable.error(e, t); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableWindowBoundary.java b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableWindowBoundary.java index f152f6f263..cbcdfc3c91 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableWindowBoundary.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/observable/ObservableWindowBoundary.java @@ -100,11 +100,9 @@ public void onNext(T t) { @Override public void onError(Throwable e) { boundaryObserver.dispose(); - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { done = true; drain(); - } else { - RxJavaPlugins.onError(e); } } @@ -144,11 +142,9 @@ void innerNext() { void innerError(Throwable e) { DisposableHelper.dispose(upstream); - if (errors.addThrowable(e)) { + if (errors.tryAddThrowableOrReport(e)) { done = true; drain(); - } else { - RxJavaPlugins.onError(e); } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/parallel/ParallelJoin.java b/src/main/java/io/reactivex/rxjava3/internal/operators/parallel/ParallelJoin.java index db26589bd1..b15fa8dfd5 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/parallel/ParallelJoin.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/parallel/ParallelJoin.java @@ -337,7 +337,7 @@ void onNext(JoinInnerSubscriber inner, T value) { if (!q.offer(value)) { inner.cancel(); - errors.addThrowable(new MissingBackpressureException("Queue full?!")); + errors.tryAddThrowableOrReport(new MissingBackpressureException("Queue full?!")); done.decrementAndGet(); drainLoop(); return; @@ -351,7 +351,7 @@ void onNext(JoinInnerSubscriber inner, T value) { if (!q.offer(value)) { if (inner.cancel()) { - errors.addThrowable(new MissingBackpressureException("Queue full?!")); + errors.tryAddThrowableOrReport(new MissingBackpressureException("Queue full?!")); done.decrementAndGet(); } } @@ -366,9 +366,10 @@ void onNext(JoinInnerSubscriber inner, T value) { @Override void onError(Throwable e) { - errors.addThrowable(e); - done.decrementAndGet(); - drain(); + if (errors.tryAddThrowableOrReport(e)) { + done.decrementAndGet(); + drain(); + } } @Override diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/single/SingleCreate.java b/src/main/java/io/reactivex/rxjava3/internal/operators/single/SingleCreate.java index 1eecc7aba9..a2164d2ec5 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/single/SingleCreate.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/single/SingleCreate.java @@ -20,6 +20,7 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Cancellable; import io.reactivex.rxjava3.internal.disposables.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; public final class SingleCreate extends Single { @@ -62,7 +63,7 @@ public void onSuccess(T value) { if (d != DisposableHelper.DISPOSED) { try { if (value == null) { - downstream.onError(new NullPointerException("onSuccess called with null. Null values are generally not allowed in 2.x operators and sources.")); + downstream.onError(ExceptionHelper.createNullPointerException("onSuccess called with a null value.")); } else { downstream.onSuccess(value); } @@ -85,7 +86,7 @@ public void onError(Throwable t) { @Override public boolean tryOnError(Throwable t) { if (t == null) { - t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + t = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } if (get() != DisposableHelper.DISPOSED) { Disposable d = getAndSet(DisposableHelper.DISPOSED); diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/single/SingleError.java b/src/main/java/io/reactivex/rxjava3/internal/operators/single/SingleError.java index 0af754a6b9..89b9bc3baa 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/single/SingleError.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/single/SingleError.java @@ -17,7 +17,7 @@ import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.functions.Supplier; import io.reactivex.rxjava3.internal.disposables.EmptyDisposable; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; public final class SingleError extends Single { @@ -32,7 +32,7 @@ protected void subscribeActual(SingleObserver observer) { Throwable error; try { - error = ObjectHelper.requireNonNull(errorSupplier.get(), "Supplier returned null throwable. Null values are generally not allowed in 2.x operators and sources."); + error = ExceptionHelper.nullCheck(errorSupplier.get(), "Supplier returned a null Throwable."); } catch (Throwable e) { Exceptions.throwIfFatal(e); error = e; diff --git a/src/main/java/io/reactivex/rxjava3/internal/util/AtomicThrowable.java b/src/main/java/io/reactivex/rxjava3/internal/util/AtomicThrowable.java index 5a4ca39df3..222008e216 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/util/AtomicThrowable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/util/AtomicThrowable.java @@ -35,10 +35,24 @@ public final class AtomicThrowable extends AtomicReference { * @param t the throwable to add * @return true if successful, false if the container has been terminated */ - public boolean addThrowable(Throwable t) { + public boolean tryAddThrowable(Throwable t) { return ExceptionHelper.addThrowable(this, t); } + /** + * Atomically adds a Throwable to this container (combining with a previous Throwable is necessary) + * or reports the error the global error handler and no changes are made. + * @param t the throwable to add + * @return true if successful, false if the container has been terminated + */ + public boolean tryAddThrowableOrReport(Throwable t) { + if (tryAddThrowable(t)) { + return true; + } + RxJavaPlugins.onError(t); + return false; + } + /** * Atomically terminate the container and return the contents of the last * non-terminal Throwable of it. @@ -142,4 +156,20 @@ public void tryTerminateConsumer(CompletableObserver consumer) { consumer.onError(ex); } } + + /** + * Tries to terminate this atomic throwable (by swapping in the TERMINATED indicator) + * and notifies the consumer if there was no error (onComplete) or there was a + * non-null, non-indicator exception contained before (onError). + * If there was a terminated indicator, the consumer is not signaled. + * @param consumer the consumer to notify + */ + public void tryTerminateConsumer(Emitter consumer) { + Throwable ex = terminate(); + if (ex == null) { + consumer.onComplete(); + } else if (ex != ExceptionHelper.TERMINATED) { + consumer.onError(ex); + } + } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/util/ExceptionHelper.java b/src/main/java/io/reactivex/rxjava3/internal/util/ExceptionHelper.java index 03546c47fe..606368d041 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/util/ExceptionHelper.java +++ b/src/main/java/io/reactivex/rxjava3/internal/util/ExceptionHelper.java @@ -143,4 +143,41 @@ public Throwable fillInStackTrace() { return this; } } + + /** + * Composes a String with a null warning message. + * @param prefix the prefix to add to the message. + * @return the composed String + * @since 3.0.0 + */ + public static String nullWarning(String prefix) { + return prefix + " Null values are generally not allowed in 3.x operators and sources."; + } + + /** + * Creates a NullPointerException with a composed message via {@link #nullWarning(String)}. + * @param prefix the prefix to add to the message. + * @return the composed String + * @since 3.0.0 + */ + public static NullPointerException createNullPointerException(String prefix) { + return new NullPointerException(nullWarning(prefix)); + } + + /** + * Similar to ObjectHelper.requireNonNull but composes the error message via + * {@link #nullWarning(String)}. + * @param the value type + * @param value the value to check + * @param prefix the prefix to the error message + * @return the value + * @throws NullPointerException if value is null + * @since 3.0.0 + */ + public static T nullCheck(T value, String prefix) { + if (value == null) { + throw createNullPointerException(prefix); + } + return value; + } } diff --git a/src/main/java/io/reactivex/rxjava3/internal/util/HalfSerializer.java b/src/main/java/io/reactivex/rxjava3/internal/util/HalfSerializer.java index b07c317ab4..54f787f55a 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/util/HalfSerializer.java +++ b/src/main/java/io/reactivex/rxjava3/internal/util/HalfSerializer.java @@ -17,7 +17,6 @@ import org.reactivestreams.Subscriber; import io.reactivex.rxjava3.core.Observer; -import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** * Utility methods to perform half-serialization: a form of serialization @@ -37,14 +36,14 @@ private HalfSerializer() { * @param subscriber the target Subscriber to emit to * @param value the value to emit * @param wip the serialization work-in-progress counter/indicator - * @param error the holder of Throwables + * @param errors the holder of Throwables */ public static void onNext(Subscriber subscriber, T value, - AtomicInteger wip, AtomicThrowable error) { + AtomicInteger wip, AtomicThrowable errors) { if (wip.get() == 0 && wip.compareAndSet(0, 1)) { subscriber.onNext(value); if (wip.decrementAndGet() != 0) { - error.tryTerminateConsumer(subscriber); + errors.tryTerminateConsumer(subscriber); } } } @@ -56,16 +55,14 @@ public static void onNext(Subscriber subscriber, T value, * @param subscriber the target Subscriber to emit to * @param ex the Throwable to emit * @param wip the serialization work-in-progress counter/indicator - * @param error the holder of Throwables + * @param errors the holder of Throwables */ public static void onError(Subscriber subscriber, Throwable ex, - AtomicInteger wip, AtomicThrowable error) { - if (error.addThrowable(ex)) { + AtomicInteger wip, AtomicThrowable errors) { + if (errors.tryAddThrowableOrReport(ex)) { if (wip.getAndIncrement() == 0) { - error.tryTerminateConsumer(subscriber); + errors.tryTerminateConsumer(subscriber); } - } else { - RxJavaPlugins.onError(ex); } } @@ -74,11 +71,11 @@ public static void onError(Subscriber subscriber, Throwable ex, * the concurrently running onNext should do that. * @param subscriber the target Subscriber to emit to * @param wip the serialization work-in-progress counter/indicator - * @param error the holder of Throwables + * @param errors the holder of Throwables */ - public static void onComplete(Subscriber subscriber, AtomicInteger wip, AtomicThrowable error) { + public static void onComplete(Subscriber subscriber, AtomicInteger wip, AtomicThrowable errors) { if (wip.getAndIncrement() == 0) { - error.tryTerminateConsumer(subscriber); + errors.tryTerminateConsumer(subscriber); } } @@ -89,14 +86,14 @@ public static void onComplete(Subscriber subscriber, AtomicInteger wip, Atomi * @param observer the target Observer to emit to * @param value the value to emit * @param wip the serialization work-in-progress counter/indicator - * @param error the holder of Throwables + * @param errors the holder of Throwables */ public static void onNext(Observer observer, T value, - AtomicInteger wip, AtomicThrowable error) { + AtomicInteger wip, AtomicThrowable errors) { if (wip.get() == 0 && wip.compareAndSet(0, 1)) { observer.onNext(value); if (wip.decrementAndGet() != 0) { - error.tryTerminateConsumer(observer); + errors.tryTerminateConsumer(observer); } } } @@ -108,16 +105,14 @@ public static void onNext(Observer observer, T value, * @param observer the target Subscriber to emit to * @param ex the Throwable to emit * @param wip the serialization work-in-progress counter/indicator - * @param error the holder of Throwables + * @param errors the holder of Throwables */ public static void onError(Observer observer, Throwable ex, - AtomicInteger wip, AtomicThrowable error) { - if (error.addThrowable(ex)) { + AtomicInteger wip, AtomicThrowable errors) { + if (errors.tryAddThrowableOrReport(ex)) { if (wip.getAndIncrement() == 0) { - error.tryTerminateConsumer(observer); + errors.tryTerminateConsumer(observer); } - } else { - RxJavaPlugins.onError(ex); } } @@ -126,11 +121,11 @@ public static void onError(Observer observer, Throwable ex, * the concurrently running onNext should do that. * @param observer the target Subscriber to emit to * @param wip the serialization work-in-progress counter/indicator - * @param error the holder of Throwables + * @param errors the holder of Throwables */ - public static void onComplete(Observer observer, AtomicInteger wip, AtomicThrowable error) { + public static void onComplete(Observer observer, AtomicInteger wip, AtomicThrowable errors) { if (wip.getAndIncrement() == 0) { - error.tryTerminateConsumer(observer); + errors.tryTerminateConsumer(observer); } } diff --git a/src/main/java/io/reactivex/rxjava3/observers/SafeObserver.java b/src/main/java/io/reactivex/rxjava3/observers/SafeObserver.java index 2cb94eab52..f7612378e2 100644 --- a/src/main/java/io/reactivex/rxjava3/observers/SafeObserver.java +++ b/src/main/java/io/reactivex/rxjava3/observers/SafeObserver.java @@ -17,6 +17,7 @@ import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.exceptions.*; import io.reactivex.rxjava3.internal.disposables.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -84,7 +85,7 @@ public void onNext(@NonNull T t) { } if (t == null) { - Throwable ex = new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + Throwable ex = ExceptionHelper.createNullPointerException("onNext called with a null value."); try { upstream.dispose(); } catch (Throwable e1) { @@ -163,7 +164,7 @@ public void onError(@NonNull Throwable t) { } if (t == null) { - t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + t = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } try { diff --git a/src/main/java/io/reactivex/rxjava3/observers/SerializedObserver.java b/src/main/java/io/reactivex/rxjava3/observers/SerializedObserver.java index 7146335706..a0ffe75cce 100644 --- a/src/main/java/io/reactivex/rxjava3/observers/SerializedObserver.java +++ b/src/main/java/io/reactivex/rxjava3/observers/SerializedObserver.java @@ -90,7 +90,7 @@ public void onNext(@NonNull T t) { } if (t == null) { upstream.dispose(); - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("onNext called with a null value.")); return; } synchronized (this) { diff --git a/src/main/java/io/reactivex/rxjava3/plugins/RxJavaPlugins.java b/src/main/java/io/reactivex/rxjava3/plugins/RxJavaPlugins.java index 380c496681..976289c542 100644 --- a/src/main/java/io/reactivex/rxjava3/plugins/RxJavaPlugins.java +++ b/src/main/java/io/reactivex/rxjava3/plugins/RxJavaPlugins.java @@ -361,7 +361,7 @@ public static void onError(@NonNull Throwable error) { Consumer f = errorHandler; if (error == null) { - error = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + error = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } else { if (!isBug(error)) { error = new UndeliverableException(error); diff --git a/src/main/java/io/reactivex/rxjava3/processors/AsyncProcessor.java b/src/main/java/io/reactivex/rxjava3/processors/AsyncProcessor.java index 7d5e84a8f2..9a75a1f4ca 100644 --- a/src/main/java/io/reactivex/rxjava3/processors/AsyncProcessor.java +++ b/src/main/java/io/reactivex/rxjava3/processors/AsyncProcessor.java @@ -17,8 +17,8 @@ import org.reactivestreams.*; import io.reactivex.rxjava3.annotations.*; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.subscriptions.DeferredScalarSubscription; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -161,7 +161,7 @@ public void onSubscribe(Subscription s) { @Override public void onNext(T t) { - ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onNext called with a null value."); if (subscribers.get() == TERMINATED) { return; } @@ -171,7 +171,7 @@ public void onNext(T t) { @SuppressWarnings("unchecked") @Override public void onError(Throwable t) { - ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onError called with a null Throwable."); if (subscribers.get() == TERMINATED) { RxJavaPlugins.onError(t); return; diff --git a/src/main/java/io/reactivex/rxjava3/processors/BehaviorProcessor.java b/src/main/java/io/reactivex/rxjava3/processors/BehaviorProcessor.java index cf212214b7..5ac1d1d607 100644 --- a/src/main/java/io/reactivex/rxjava3/processors/BehaviorProcessor.java +++ b/src/main/java/io/reactivex/rxjava3/processors/BehaviorProcessor.java @@ -268,7 +268,7 @@ public void onSubscribe(Subscription s) { @Override public void onNext(T t) { - ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onNext called with a null value."); if (terminalEvent.get() != null) { return; @@ -282,7 +282,7 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onError called with a null Throwable."); if (!terminalEvent.compareAndSet(null, t)) { RxJavaPlugins.onError(t); return; @@ -311,8 +311,8 @@ public void onComplete() { * This method should be called in a sequential manner just like the onXXX methods * of the PublishProcessor. *

- * Calling with null will terminate the PublishProcessor and a NullPointerException - * is signalled to the Subscribers. + * Calling with a null value will terminate the PublishProcessor and a NullPointerException + * is signaled to the Subscribers. *

History: 2.0.8 - experimental * @param t the item to emit, not null * @return true if the item was emitted to all Subscribers @@ -320,7 +320,7 @@ public void onComplete() { */ public boolean offer(T t) { if (t == null) { - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("offer called with a null value.")); return true; } BehaviorSubscription[] array = subscribers.get(); diff --git a/src/main/java/io/reactivex/rxjava3/processors/MulticastProcessor.java b/src/main/java/io/reactivex/rxjava3/processors/MulticastProcessor.java index 7d613a0939..fbf3f17521 100644 --- a/src/main/java/io/reactivex/rxjava3/processors/MulticastProcessor.java +++ b/src/main/java/io/reactivex/rxjava3/processors/MulticastProcessor.java @@ -23,6 +23,7 @@ import io.reactivex.rxjava3.internal.fuseable.*; import io.reactivex.rxjava3.internal.queue.*; import io.reactivex.rxjava3.internal.subscriptions.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -292,7 +293,7 @@ public void onNext(T t) { return; } if (fusionMode == QueueSubscription.NONE) { - ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onNext called with a null value."); if (!queue.offer(t)) { SubscriptionHelper.cancel(upstream); onError(new MissingBackpressureException()); @@ -312,7 +313,7 @@ public boolean offer(T t) { if (once.get()) { return false; } - ObjectHelper.requireNonNull(t, "offer called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "offer called with a null value."); if (fusionMode == QueueSubscription.NONE) { if (queue.offer(t)) { drain(); @@ -324,7 +325,7 @@ public boolean offer(T t) { @Override public void onError(Throwable t) { - ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onError called with a null Throwable."); if (once.compareAndSet(false, true)) { error = t; done = true; diff --git a/src/main/java/io/reactivex/rxjava3/processors/PublishProcessor.java b/src/main/java/io/reactivex/rxjava3/processors/PublishProcessor.java index 54c85a6097..2d44f60f05 100644 --- a/src/main/java/io/reactivex/rxjava3/processors/PublishProcessor.java +++ b/src/main/java/io/reactivex/rxjava3/processors/PublishProcessor.java @@ -18,9 +18,8 @@ import io.reactivex.rxjava3.annotations.*; import io.reactivex.rxjava3.exceptions.MissingBackpressureException; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; -import io.reactivex.rxjava3.internal.util.BackpressureHelper; +import io.reactivex.rxjava3.internal.util.*; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -238,7 +237,7 @@ public void onSubscribe(Subscription s) { @Override public void onNext(T t) { - ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onNext called with a null value."); for (PublishSubscription s : subscribers.get()) { s.onNext(t); } @@ -247,7 +246,7 @@ public void onNext(T t) { @SuppressWarnings("unchecked") @Override public void onError(Throwable t) { - ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onError called with a null Throwable."); if (subscribers.get() == TERMINATED) { RxJavaPlugins.onError(t); return; @@ -277,8 +276,8 @@ public void onComplete() { * This method should be called in a sequential manner just like the onXXX methods * of the PublishProcessor. *

- * Calling with null will terminate the PublishProcessor and a NullPointerException - * is signalled to the Subscribers. + * Calling with a null value will terminate the PublishProcessor and a NullPointerException + * is signaled to the Subscribers. *

History: 2.0.8 - experimental * @param t the item to emit, not null * @return true if the item was emitted to all Subscribers @@ -286,7 +285,7 @@ public void onComplete() { */ public boolean offer(T t) { if (t == null) { - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("offer called with a null value.")); return true; } PublishSubscription[] array = subscribers.get(); diff --git a/src/main/java/io/reactivex/rxjava3/processors/ReplayProcessor.java b/src/main/java/io/reactivex/rxjava3/processors/ReplayProcessor.java index 988ff4418d..1ab964a6dd 100644 --- a/src/main/java/io/reactivex/rxjava3/processors/ReplayProcessor.java +++ b/src/main/java/io/reactivex/rxjava3/processors/ReplayProcessor.java @@ -24,7 +24,7 @@ import io.reactivex.rxjava3.core.Scheduler; import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper; -import io.reactivex.rxjava3.internal.util.BackpressureHelper; +import io.reactivex.rxjava3.internal.util.*; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -353,7 +353,7 @@ public void onSubscribe(Subscription s) { @Override public void onNext(T t) { - ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onNext called with a null value."); if (done) { return; @@ -370,7 +370,7 @@ public void onNext(T t) { @SuppressWarnings("unchecked") @Override public void onError(Throwable t) { - ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onError called with a null Throwable."); if (done) { RxJavaPlugins.onError(t); diff --git a/src/main/java/io/reactivex/rxjava3/processors/UnicastProcessor.java b/src/main/java/io/reactivex/rxjava3/processors/UnicastProcessor.java index 31b9f4aca4..d5c1c1b072 100644 --- a/src/main/java/io/reactivex/rxjava3/processors/UnicastProcessor.java +++ b/src/main/java/io/reactivex/rxjava3/processors/UnicastProcessor.java @@ -22,7 +22,7 @@ import io.reactivex.rxjava3.internal.fuseable.QueueSubscription; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; import io.reactivex.rxjava3.internal.subscriptions.*; -import io.reactivex.rxjava3.internal.util.BackpressureHelper; +import io.reactivex.rxjava3.internal.util.*; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -446,7 +446,7 @@ public void onSubscribe(Subscription s) { @Override public void onNext(T t) { - ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onNext called with a null value."); if (done || cancelled) { return; @@ -458,7 +458,7 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onError called with a null Throwable."); if (done || cancelled) { RxJavaPlugins.onError(t); diff --git a/src/main/java/io/reactivex/rxjava3/subjects/AsyncSubject.java b/src/main/java/io/reactivex/rxjava3/subjects/AsyncSubject.java index 5190d75013..174c98c4f5 100644 --- a/src/main/java/io/reactivex/rxjava3/subjects/AsyncSubject.java +++ b/src/main/java/io/reactivex/rxjava3/subjects/AsyncSubject.java @@ -18,8 +18,8 @@ import io.reactivex.rxjava3.annotations.*; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; import io.reactivex.rxjava3.internal.observers.DeferredScalarDisposable; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -150,7 +150,7 @@ public void onSubscribe(Disposable d) { @Override public void onNext(T t) { - ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onNext called with a null value."); if (subscribers.get() == TERMINATED) { return; } @@ -160,7 +160,7 @@ public void onNext(T t) { @SuppressWarnings("unchecked") @Override public void onError(Throwable t) { - ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onError called with a null Throwable."); if (subscribers.get() == TERMINATED) { RxJavaPlugins.onError(t); return; diff --git a/src/main/java/io/reactivex/rxjava3/subjects/BehaviorSubject.java b/src/main/java/io/reactivex/rxjava3/subjects/BehaviorSubject.java index f8f4bb3848..45ddb72a51 100644 --- a/src/main/java/io/reactivex/rxjava3/subjects/BehaviorSubject.java +++ b/src/main/java/io/reactivex/rxjava3/subjects/BehaviorSubject.java @@ -250,7 +250,7 @@ public void onSubscribe(Disposable d) { @Override public void onNext(T t) { - ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onNext called with a null value."); if (terminalEvent.get() != null) { return; @@ -264,7 +264,7 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onError called with a null Throwable."); if (!terminalEvent.compareAndSet(null, t)) { RxJavaPlugins.onError(t); return; diff --git a/src/main/java/io/reactivex/rxjava3/subjects/CompletableSubject.java b/src/main/java/io/reactivex/rxjava3/subjects/CompletableSubject.java index 0b369e4b43..bbb4b24b0c 100644 --- a/src/main/java/io/reactivex/rxjava3/subjects/CompletableSubject.java +++ b/src/main/java/io/reactivex/rxjava3/subjects/CompletableSubject.java @@ -18,7 +18,7 @@ import io.reactivex.rxjava3.annotations.*; import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.disposables.Disposable; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -119,7 +119,7 @@ public void onSubscribe(Disposable d) { @Override public void onError(Throwable e) { - ObjectHelper.requireNonNull(e, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(e, "onError called with a null Throwable."); if (once.compareAndSet(false, true)) { this.error = e; for (CompletableDisposable md : observers.getAndSet(TERMINATED)) { diff --git a/src/main/java/io/reactivex/rxjava3/subjects/MaybeSubject.java b/src/main/java/io/reactivex/rxjava3/subjects/MaybeSubject.java index 9546783736..a2f62524f0 100644 --- a/src/main/java/io/reactivex/rxjava3/subjects/MaybeSubject.java +++ b/src/main/java/io/reactivex/rxjava3/subjects/MaybeSubject.java @@ -18,7 +18,7 @@ import io.reactivex.rxjava3.annotations.*; import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.disposables.Disposable; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -150,7 +150,7 @@ public void onSubscribe(Disposable d) { @SuppressWarnings("unchecked") @Override public void onSuccess(T value) { - ObjectHelper.requireNonNull(value, "onSuccess called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(value, "onSuccess called with a null value."); if (once.compareAndSet(false, true)) { this.value = value; for (MaybeDisposable md : observers.getAndSet(TERMINATED)) { @@ -162,7 +162,7 @@ public void onSuccess(T value) { @SuppressWarnings("unchecked") @Override public void onError(Throwable e) { - ObjectHelper.requireNonNull(e, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(e, "onError called with a null Throwable."); if (once.compareAndSet(false, true)) { this.error = e; for (MaybeDisposable md : observers.getAndSet(TERMINATED)) { diff --git a/src/main/java/io/reactivex/rxjava3/subjects/PublishSubject.java b/src/main/java/io/reactivex/rxjava3/subjects/PublishSubject.java index 5c706c5c92..a81d6062fd 100644 --- a/src/main/java/io/reactivex/rxjava3/subjects/PublishSubject.java +++ b/src/main/java/io/reactivex/rxjava3/subjects/PublishSubject.java @@ -18,7 +18,7 @@ import io.reactivex.rxjava3.annotations.*; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -221,7 +221,7 @@ public void onSubscribe(Disposable d) { @Override public void onNext(T t) { - ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onNext called with a null value."); for (PublishDisposable pd : subscribers.get()) { pd.onNext(t); } @@ -230,7 +230,7 @@ public void onNext(T t) { @SuppressWarnings("unchecked") @Override public void onError(Throwable t) { - ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onError called with a null Throwable."); if (subscribers.get() == TERMINATED) { RxJavaPlugins.onError(t); return; diff --git a/src/main/java/io/reactivex/rxjava3/subjects/ReplaySubject.java b/src/main/java/io/reactivex/rxjava3/subjects/ReplaySubject.java index 477af44513..2d9dbe779a 100644 --- a/src/main/java/io/reactivex/rxjava3/subjects/ReplaySubject.java +++ b/src/main/java/io/reactivex/rxjava3/subjects/ReplaySubject.java @@ -23,7 +23,7 @@ import io.reactivex.rxjava3.core.Scheduler; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.internal.functions.ObjectHelper; -import io.reactivex.rxjava3.internal.util.NotificationLite; +import io.reactivex.rxjava3.internal.util.*; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -340,7 +340,7 @@ public void onSubscribe(Disposable d) { @Override public void onNext(T t) { - ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onNext called with a null value."); if (done) { return; } @@ -355,7 +355,7 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onError called with a null Throwable."); if (done) { RxJavaPlugins.onError(t); return; diff --git a/src/main/java/io/reactivex/rxjava3/subjects/SingleSubject.java b/src/main/java/io/reactivex/rxjava3/subjects/SingleSubject.java index 85be8f952d..fdd1c806f6 100644 --- a/src/main/java/io/reactivex/rxjava3/subjects/SingleSubject.java +++ b/src/main/java/io/reactivex/rxjava3/subjects/SingleSubject.java @@ -18,7 +18,7 @@ import io.reactivex.rxjava3.annotations.*; import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.disposables.Disposable; -import io.reactivex.rxjava3.internal.functions.ObjectHelper; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -134,7 +134,7 @@ public void onSubscribe(@NonNull Disposable d) { @SuppressWarnings("unchecked") @Override public void onSuccess(@NonNull T value) { - ObjectHelper.requireNonNull(value, "onSuccess called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(value, "onSuccess called with a null value."); if (once.compareAndSet(false, true)) { this.value = value; for (SingleDisposable md : observers.getAndSet(TERMINATED)) { @@ -146,7 +146,7 @@ public void onSuccess(@NonNull T value) { @SuppressWarnings("unchecked") @Override public void onError(@NonNull Throwable e) { - ObjectHelper.requireNonNull(e, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(e, "onError called with a null Throwable."); if (once.compareAndSet(false, true)) { this.error = e; for (SingleDisposable md : observers.getAndSet(TERMINATED)) { diff --git a/src/main/java/io/reactivex/rxjava3/subjects/UnicastSubject.java b/src/main/java/io/reactivex/rxjava3/subjects/UnicastSubject.java index 767e3eb332..b709a96d6c 100644 --- a/src/main/java/io/reactivex/rxjava3/subjects/UnicastSubject.java +++ b/src/main/java/io/reactivex/rxjava3/subjects/UnicastSubject.java @@ -23,6 +23,7 @@ import io.reactivex.rxjava3.internal.fuseable.SimpleQueue; import io.reactivex.rxjava3.internal.observers.BasicIntQueueDisposable; import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -325,7 +326,7 @@ public void onSubscribe(Disposable d) { @Override public void onNext(T t) { - ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onNext called with a null value."); if (done || disposed) { return; } @@ -335,7 +336,7 @@ public void onNext(T t) { @Override public void onError(Throwable t) { - ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources."); + ExceptionHelper.nullCheck(t, "onError called with a null Throwable."); if (done || disposed) { RxJavaPlugins.onError(t); return; diff --git a/src/main/java/io/reactivex/rxjava3/subscribers/SafeSubscriber.java b/src/main/java/io/reactivex/rxjava3/subscribers/SafeSubscriber.java index 9311099e63..096a99e623 100644 --- a/src/main/java/io/reactivex/rxjava3/subscribers/SafeSubscriber.java +++ b/src/main/java/io/reactivex/rxjava3/subscribers/SafeSubscriber.java @@ -17,6 +17,7 @@ import io.reactivex.rxjava3.core.FlowableSubscriber; import io.reactivex.rxjava3.exceptions.*; import io.reactivex.rxjava3.internal.subscriptions.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; /** @@ -74,7 +75,7 @@ public void onNext(T t) { } if (t == null) { - Throwable ex = new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + Throwable ex = ExceptionHelper.createNullPointerException("onNext called with a null Throwable."); try { upstream.cancel(); } catch (Throwable e1) { @@ -152,7 +153,7 @@ public void onError(Throwable t) { } if (t == null) { - t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."); + t = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } try { diff --git a/src/main/java/io/reactivex/rxjava3/subscribers/SerializedSubscriber.java b/src/main/java/io/reactivex/rxjava3/subscribers/SerializedSubscriber.java index 85386c1954..92ecbbe6d0 100644 --- a/src/main/java/io/reactivex/rxjava3/subscribers/SerializedSubscriber.java +++ b/src/main/java/io/reactivex/rxjava3/subscribers/SerializedSubscriber.java @@ -78,7 +78,7 @@ public void onNext(T t) { } if (t == null) { upstream.cancel(); - onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); + onError(ExceptionHelper.createNullPointerException("onNext called with a null value.")); return; } synchronized (this) { diff --git a/src/test/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableDistinctTest.java b/src/test/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableDistinctTest.java index 1c21705a9f..70682d9e03 100644 --- a/src/test/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableDistinctTest.java +++ b/src/test/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableDistinctTest.java @@ -29,6 +29,7 @@ import io.reactivex.rxjava3.internal.functions.Functions; import io.reactivex.rxjava3.internal.fuseable.*; import io.reactivex.rxjava3.internal.subscriptions.BooleanSubscription; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import io.reactivex.rxjava3.processors.UnicastProcessor; import io.reactivex.rxjava3.testsupport.*; @@ -193,7 +194,7 @@ public Collection get() throws Exception { }) .to(TestHelper.testConsumer()) .assertFailure(NullPointerException.class) - .assertErrorMessage("The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + .assertErrorMessage(ExceptionHelper.nullWarning("The collectionSupplier returned a null Collection.")); } @Test diff --git a/src/test/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToListTest.java b/src/test/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToListTest.java index 72e2bf80c6..66d2164b70 100644 --- a/src/test/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToListTest.java +++ b/src/test/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableToListTest.java @@ -26,6 +26,7 @@ import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.exceptions.TestException; import io.reactivex.rxjava3.functions.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.observers.TestObserver; import io.reactivex.rxjava3.processors.PublishProcessor; import io.reactivex.rxjava3.subscribers.TestSubscriber; @@ -244,7 +245,7 @@ public Collection get() throws Exception { .toFlowable() .to(TestHelper.>testConsumer()) .assertFailure(NullPointerException.class) - .assertErrorMessage("The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + .assertErrorMessage(ExceptionHelper.nullWarning("The collectionSupplier returned a null Collection.")); } @SuppressWarnings("unchecked") @@ -273,7 +274,7 @@ public Collection get() throws Exception { }) .to(TestHelper.>testConsumer()) .assertFailure(NullPointerException.class) - .assertErrorMessage("The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + .assertErrorMessage(ExceptionHelper.nullWarning("The collectionSupplier returned a null Collection.")); } @Test diff --git a/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableDistinctTest.java b/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableDistinctTest.java index da842b1f9b..2a9d889ba2 100644 --- a/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableDistinctTest.java +++ b/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableDistinctTest.java @@ -30,6 +30,7 @@ import io.reactivex.rxjava3.functions.*; import io.reactivex.rxjava3.internal.functions.Functions; import io.reactivex.rxjava3.internal.fuseable.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import io.reactivex.rxjava3.subjects.UnicastSubject; import io.reactivex.rxjava3.testsupport.*; @@ -194,7 +195,7 @@ public Collection get() throws Exception { }) .to(TestHelper.testConsumer()) .assertFailure(NullPointerException.class) - .assertErrorMessage("The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + .assertErrorMessage(ExceptionHelper.nullWarning("The collectionSupplier returned a null Collection.")); } @Test diff --git a/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToListTest.java b/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToListTest.java index 33766df112..1981c2b5af 100644 --- a/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToListTest.java +++ b/src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableToListTest.java @@ -27,6 +27,7 @@ import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.exceptions.TestException; import io.reactivex.rxjava3.functions.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.testsupport.TestHelper; public class ObservableToListTest extends RxJavaTest { @@ -216,7 +217,7 @@ public Collection get() throws Exception { .toObservable() .to(TestHelper.>testConsumer()) .assertFailure(NullPointerException.class) - .assertErrorMessage("The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + .assertErrorMessage(ExceptionHelper.nullWarning("The collectionSupplier returned a null Collection.")); } @SuppressWarnings("unchecked") @@ -245,7 +246,7 @@ public Collection get() throws Exception { }) .to(TestHelper.>testConsumer()) .assertFailure(NullPointerException.class) - .assertErrorMessage("The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources."); + .assertErrorMessage(ExceptionHelper.nullWarning("The collectionSupplier returned a null Collection.")); } @Test diff --git a/src/test/java/io/reactivex/rxjava3/internal/util/AtomicThrowableTest.java b/src/test/java/io/reactivex/rxjava3/internal/util/AtomicThrowableTest.java index 377fd6c873..86f823e22e 100644 --- a/src/test/java/io/reactivex/rxjava3/internal/util/AtomicThrowableTest.java +++ b/src/test/java/io/reactivex/rxjava3/internal/util/AtomicThrowableTest.java @@ -248,4 +248,86 @@ public void tryTerminateConsumerCompletableObserverTerminated() { ex.tryTerminateConsumer((CompletableObserver)to); to.assertEmpty(); } + + static Emitter wrapToEmitter(final Observer observer) { + return new Emitter() { + @Override + public void onNext(T value) { + observer.onNext(value); + } + + @Override + public void onError(Throwable error) { + observer.onError(error); + } + + @Override + public void onComplete() { + observer.onComplete(); + } + }; + } + + @Test + public void tryTerminateConsumerEmitterNoError() { + TestObserver to = new TestObserver(); + to.onSubscribe(Disposables.empty()); + + AtomicThrowable ex = new AtomicThrowable(); + ex.tryTerminateConsumer(wrapToEmitter(to)); + to.assertResult(); + } + + @Test + public void tryTerminateConsumerEmitterError() { + TestObserver to = new TestObserver(); + to.onSubscribe(Disposables.empty()); + + AtomicThrowable ex = new AtomicThrowable(); + ex.set(new TestException()); + ex.tryTerminateConsumer(wrapToEmitter(to)); + to.assertFailure(TestException.class); + } + + @Test + public void tryTerminateConsumerEmitterTerminated() { + TestObserver to = new TestObserver(); + to.onSubscribe(Disposables.empty()); + + AtomicThrowable ex = new AtomicThrowable(); + ex.terminate(); + ex.tryTerminateConsumer(wrapToEmitter(to)); + to.assertEmpty(); + } + + @Test + public void tryAddThrowableOrReportNull() { + List errors = TestHelper.trackPluginErrors(); + try { + + AtomicThrowable ex = new AtomicThrowable(); + ex.tryAddThrowableOrReport(new TestException()); + + assertTrue("" + errors, errors.isEmpty()); + } finally { + RxJavaPlugins.reset(); + } + } + + @Test + public void tryAddThrowableOrReportTerminated() { + List errors = TestHelper.trackPluginErrors(); + try { + + AtomicThrowable ex = new AtomicThrowable(); + ex.terminate(); + + assertFalse(ex.tryAddThrowableOrReport(new TestException())); + + assertFalse("" + errors, errors.isEmpty()); + TestHelper.assertUndeliverable(errors, 0, TestException.class); + } finally { + RxJavaPlugins.reset(); + } + } } diff --git a/src/test/java/io/reactivex/rxjava3/observers/SerializedObserverTest.java b/src/test/java/io/reactivex/rxjava3/observers/SerializedObserverTest.java index ecb86d8417..1d467242f5 100644 --- a/src/test/java/io/reactivex/rxjava3/observers/SerializedObserverTest.java +++ b/src/test/java/io/reactivex/rxjava3/observers/SerializedObserverTest.java @@ -26,6 +26,7 @@ import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.disposables.*; import io.reactivex.rxjava3.exceptions.TestException; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import io.reactivex.rxjava3.schedulers.Schedulers; import io.reactivex.rxjava3.testsupport.*; @@ -1139,6 +1140,6 @@ public void nullOnNext() { so.onNext(null); - to.assertFailureAndMessage(NullPointerException.class, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + to.assertFailureAndMessage(NullPointerException.class, ExceptionHelper.nullWarning("onNext called with a null value.")); } } diff --git a/src/test/java/io/reactivex/rxjava3/plugins/RxJavaPluginsTest.java b/src/test/java/io/reactivex/rxjava3/plugins/RxJavaPluginsTest.java index c5cd3799ff..5e0b5ab207 100644 --- a/src/test/java/io/reactivex/rxjava3/plugins/RxJavaPluginsTest.java +++ b/src/test/java/io/reactivex/rxjava3/plugins/RxJavaPluginsTest.java @@ -45,6 +45,7 @@ import io.reactivex.rxjava3.internal.operators.single.SingleJust; import io.reactivex.rxjava3.internal.schedulers.ImmediateThinScheduler; import io.reactivex.rxjava3.internal.subscriptions.ScalarSubscription; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.observables.ConnectableObservable; import io.reactivex.rxjava3.parallel.ParallelFlowable; import io.reactivex.rxjava3.schedulers.Schedulers; @@ -1534,7 +1535,7 @@ public void accept(final Throwable throwable) throws Exception { RxJavaPlugins.onError(null); final Throwable throwable = t.get(); - assertEquals("onError called with null. Null values are generally not allowed in 2.x operators and sources.", throwable.getMessage()); + assertEquals(ExceptionHelper.nullWarning("onError called with a null Throwable."), throwable.getMessage()); assertTrue(throwable instanceof NullPointerException); } finally { RxJavaPlugins.reset(); diff --git a/src/test/java/io/reactivex/rxjava3/processors/FlowableProcessorTest.java b/src/test/java/io/reactivex/rxjava3/processors/FlowableProcessorTest.java index f25b030757..ae659623e0 100644 --- a/src/test/java/io/reactivex/rxjava3/processors/FlowableProcessorTest.java +++ b/src/test/java/io/reactivex/rxjava3/processors/FlowableProcessorTest.java @@ -18,6 +18,7 @@ import org.junit.Test; import io.reactivex.rxjava3.core.RxJavaTest; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; public abstract class FlowableProcessorTest extends RxJavaTest { @@ -31,7 +32,7 @@ public void onNextNull() { p.onNext(null); fail("No NullPointerException thrown"); } catch (NullPointerException ex) { - assertEquals("onNext called with null. Null values are generally not allowed in 2.x operators and sources.", ex.getMessage()); + assertEquals(ExceptionHelper.nullWarning("onNext called with a null value."), ex.getMessage()); } p.test().assertEmpty().cancel(); @@ -45,7 +46,7 @@ public void onErrorNull() { p.onError(null); fail("No NullPointerException thrown"); } catch (NullPointerException ex) { - assertEquals("onError called with null. Null values are generally not allowed in 2.x operators and sources.", ex.getMessage()); + assertEquals(ExceptionHelper.nullWarning("onError called with a null Throwable."), ex.getMessage()); } p.test().assertEmpty().cancel(); diff --git a/src/test/java/io/reactivex/rxjava3/subjects/CompletableSubjectTest.java b/src/test/java/io/reactivex/rxjava3/subjects/CompletableSubjectTest.java index 764c36d7f6..34aaff3831 100644 --- a/src/test/java/io/reactivex/rxjava3/subjects/CompletableSubjectTest.java +++ b/src/test/java/io/reactivex/rxjava3/subjects/CompletableSubjectTest.java @@ -22,6 +22,7 @@ import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.disposables.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.observers.TestObserver; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import io.reactivex.rxjava3.testsupport.TestHelper; @@ -129,7 +130,7 @@ public void nullThrowable() { cs.onError(null); fail("No NullPointerException thrown"); } catch (NullPointerException ex) { - assertEquals("onError called with null. Null values are generally not allowed in 2.x operators and sources.", ex.getMessage()); + assertEquals(ExceptionHelper.nullWarning("onError called with a null Throwable."), ex.getMessage()); } cs.test().assertEmpty().dispose(); diff --git a/src/test/java/io/reactivex/rxjava3/subjects/SingleSubjectTest.java b/src/test/java/io/reactivex/rxjava3/subjects/SingleSubjectTest.java index 237cd03244..7c07b63f0a 100644 --- a/src/test/java/io/reactivex/rxjava3/subjects/SingleSubjectTest.java +++ b/src/test/java/io/reactivex/rxjava3/subjects/SingleSubjectTest.java @@ -22,6 +22,7 @@ import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.disposables.*; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.observers.TestObserver; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import io.reactivex.rxjava3.testsupport.TestHelper; @@ -135,7 +136,7 @@ public void nullValue() { ss.onSuccess(null); fail("No NullPointerException thrown"); } catch (NullPointerException ex) { - assertEquals("onSuccess called with null. Null values are generally not allowed in 2.x operators and sources.", ex.getMessage()); + assertEquals(ExceptionHelper.nullWarning("onSuccess called with a null value."), ex.getMessage()); } ss.test().assertEmpty().dispose(); @@ -149,7 +150,7 @@ public void nullThrowable() { ss.onError(null); fail("No NullPointerException thrown"); } catch (NullPointerException ex) { - assertEquals("onError called with null. Null values are generally not allowed in 2.x operators and sources.", ex.getMessage()); + assertEquals(ExceptionHelper.nullWarning("onError called with a null Throwable."), ex.getMessage()); } ss.test().assertEmpty().dispose(); diff --git a/src/test/java/io/reactivex/rxjava3/subjects/SubjectTest.java b/src/test/java/io/reactivex/rxjava3/subjects/SubjectTest.java index 42c916f779..ab22d10a0c 100644 --- a/src/test/java/io/reactivex/rxjava3/subjects/SubjectTest.java +++ b/src/test/java/io/reactivex/rxjava3/subjects/SubjectTest.java @@ -18,6 +18,7 @@ import org.junit.Test; import io.reactivex.rxjava3.core.RxJavaTest; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; public abstract class SubjectTest extends RxJavaTest { @@ -31,7 +32,7 @@ public void onNextNull() { p.onNext(null); fail("No NullPointerException thrown"); } catch (NullPointerException ex) { - assertEquals("onNext called with null. Null values are generally not allowed in 2.x operators and sources.", ex.getMessage()); + assertEquals(ExceptionHelper.nullWarning("onNext called with a null value."), ex.getMessage()); } p.test().assertEmpty().dispose(); @@ -45,7 +46,7 @@ public void onErrorNull() { p.onError(null); fail("No NullPointerException thrown"); } catch (NullPointerException ex) { - assertEquals("onError called with null. Null values are generally not allowed in 2.x operators and sources.", ex.getMessage()); + assertEquals(ExceptionHelper.nullWarning("onError called with a null Throwable."), ex.getMessage()); } p.test().assertEmpty().dispose(); diff --git a/src/test/java/io/reactivex/rxjava3/subscribers/SerializedSubscriberTest.java b/src/test/java/io/reactivex/rxjava3/subscribers/SerializedSubscriberTest.java index ac541e2bcd..09b800d43e 100644 --- a/src/test/java/io/reactivex/rxjava3/subscribers/SerializedSubscriberTest.java +++ b/src/test/java/io/reactivex/rxjava3/subscribers/SerializedSubscriberTest.java @@ -27,6 +27,7 @@ import io.reactivex.rxjava3.core.*; import io.reactivex.rxjava3.exceptions.TestException; import io.reactivex.rxjava3.internal.subscriptions.BooleanSubscription; +import io.reactivex.rxjava3.internal.util.ExceptionHelper; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import io.reactivex.rxjava3.schedulers.Schedulers; import io.reactivex.rxjava3.testsupport.*; @@ -1131,6 +1132,6 @@ public void nullOnNext() { so.onNext(null); - ts.assertFailureAndMessage(NullPointerException.class, "onNext called with null. Null values are generally not allowed in 2.x operators and sources."); + ts.assertFailureAndMessage(NullPointerException.class, ExceptionHelper.nullWarning("onNext called with a null value.")); } }