/
githubmirror
/
RxJava
Обзор
Документация
Войти
/
githubmirror
/
RxJava
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
4.x
src/main/java/io/reactivex/rxjava4/observers/SafeObserver.java
222 строки
7 KB
akarnokd
Package shift from .rxjava3 to .rxjava4
18 мар 2026, 18:10
18 мар 2026, 18:10
31e32bf
Код
Авторство
О чём код?
/* * Copyright (c) 2016-present, RxJava Contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See * the License for the specific language governing permissions and limitations under the License. */ package io.reactivex.rxjava4.observers; import io.reactivex.rxjava4.annotations.NonNull; import io.reactivex.rxjava4.core.Observer; import io.reactivex.rxjava4.disposables.Disposable; import io.reactivex.rxjava4.exceptions.*; import io.reactivex.rxjava4.internal.disposables.*; import io.reactivex.rxjava4.internal.util.ExceptionHelper; import io.reactivex.rxjava4.plugins.RxJavaPlugins; /** * Wraps another {@link Observer} and ensures all {@code onXXX} methods conform the protocol * (except the requirement for serialized access). * * @param <T> the value type */ public final class SafeObserver<T> implements Observer<T>, Disposable { /** The actual Subscriber. */ final Observer<? super T> downstream; /** The subscription. */ Disposable upstream; /** Indicates a terminal state. */ boolean done; /** * Constructs a {@code SafeObserver} by wrapping the given actual {@link Observer}. * @param downstream the actual {@code Observer} to wrap, not {@code null} (not validated) */ public SafeObserver(@NonNull Observer<? super T> downstream) { this.downstream = downstream; } @Override public void onSubscribe(@NonNull Disposable d) { if (DisposableHelper.validate(this.upstream, d)) { this.upstream = d; try { downstream.onSubscribe(this); } catch (Throwable e) { Exceptions.throwIfFatal(e); done = true; // can't call onError because the actual's state may be corrupt at this point try { d.dispose(); } catch (Throwable e1) { Exceptions.throwIfFatal(e1); RxJavaPlugins.onError(new CompositeException(e, e1)); return; } RxJavaPlugins.onError(e); } } } @Override public void dispose() { upstream.dispose(); } @Override public boolean isDisposed() { return upstream.isDisposed(); } @Override public void onNext(@NonNull T t) { if (done) { return; } if (upstream == null) { onNextNoSubscription(); return; } if (t == null) { Throwable ex = ExceptionHelper.createNullPointerException("onNext called with a null value."); try { upstream.dispose(); } catch (Throwable e1) { Exceptions.throwIfFatal(e1); onError(new CompositeException(ex, e1)); return; } onError(ex); return; } try { downstream.onNext(t); } catch (Throwable e) { Exceptions.throwIfFatal(e); try { upstream.dispose(); } catch (Throwable e1) { Exceptions.throwIfFatal(e1); onError(new CompositeException(e, e1)); return; } onError(e); } } void onNextNoSubscription() { done = true; Throwable ex = new NullPointerException("Subscription not set!"); try { downstream.onSubscribe(EmptyDisposable.INSTANCE); } catch (Throwable e) { Exceptions.throwIfFatal(e); // can't call onError because the actual's state may be corrupt at this point RxJavaPlugins.onError(new CompositeException(ex, e)); return; } try { downstream.onError(ex); } catch (Throwable e) { Exceptions.throwIfFatal(e); // if onError failed, all that's left is to report the error to plugins RxJavaPlugins.onError(new CompositeException(ex, e)); } } @Override public void onError(@NonNull Throwable t) { if (done) { RxJavaPlugins.onError(t); return; } done = true; if (upstream == null) { Throwable npe = new NullPointerException("Subscription not set!"); try { downstream.onSubscribe(EmptyDisposable.INSTANCE); } catch (Throwable e) { Exceptions.throwIfFatal(e); // can't call onError because the actual's state may be corrupt at this point RxJavaPlugins.onError(new CompositeException(t, npe, e)); return; } try { downstream.onError(new CompositeException(t, npe)); } catch (Throwable e) { Exceptions.throwIfFatal(e); // if onError failed, all that's left is to report the error to plugins RxJavaPlugins.onError(new CompositeException(t, npe, e)); } return; } if (t == null) { t = ExceptionHelper.createNullPointerException("onError called with a null Throwable."); } try { downstream.onError(t); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); RxJavaPlugins.onError(new CompositeException(t, ex)); } } @Override public void onComplete() { if (done) { return; } done = true; if (upstream == null) { onCompleteNoSubscription(); return; } try { downstream.onComplete(); } catch (Throwable e) { Exceptions.throwIfFatal(e); RxJavaPlugins.onError(e); } } void onCompleteNoSubscription() { Throwable ex = new NullPointerException("Subscription not set!"); try { downstream.onSubscribe(EmptyDisposable.INSTANCE); } catch (Throwable e) { Exceptions.throwIfFatal(e); // can't call onError because the actual's state may be corrupt at this point RxJavaPlugins.onError(new CompositeException(ex, e)); return; } try { downstream.onError(ex); } catch (Throwable e) { Exceptions.throwIfFatal(e); // if onError failed, all that's left is to report the error to plugins RxJavaPlugins.onError(new CompositeException(ex, e)); } } }