All Projects → uber → Rxdogtag

uber / Rxdogtag

Licence: apache-2.0
Automatic tagging of RxJava 2+ originating subscribe points for onError() investigation.

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Rxdogtag

Rxfingerprint
Android Fingerprint authentication and encryption with RxJava
Stars: ✭ 373 (-37.94%)
Mutual labels:  rxjava, rxjava2
Android Mvp Architecture
This repository contains a detailed sample app that implements MVP architecture using Dagger2, GreenDao, RxJava2, FastAndroidNetworking and PlaceholderView
Stars: ✭ 4,360 (+625.46%)
Mutual labels:  rxjava, rxjava2
Rxcache
简单一步,缓存搞定。这是一个专用于 RxJava,解决 Android 中对任何 Observable 发出的结果做缓存处理的框架
Stars: ✭ 377 (-37.27%)
Mutual labels:  rxjava, rxjava2
Kotlinmvp
🔥 基于Kotlin+MVP+Retrofit+RxJava+Glide 等架构实现短视频类小项目,简约风格及详细注释,欢迎 star or fork!
Stars: ✭ 3,488 (+480.37%)
Mutual labels:  rxjava, rxjava2
Traceur
Easier RxJava2 debugging with better stacktraces
Stars: ✭ 502 (-16.47%)
Mutual labels:  rxjava, rxjava2
Androidproject
Android 技术中台,但愿人长久,搬砖不再有
Stars: ✭ 4,398 (+631.78%)
Mutual labels:  rxjava, rxjava2
Roxie
Lightweight Android library for building reactive apps.
Stars: ✭ 441 (-26.62%)
Mutual labels:  rxjava, rxjava2
Freezer
A simple & fluent Android ORM, how can it be easier ? RxJava2 compatible
Stars: ✭ 326 (-45.76%)
Mutual labels:  rxjava, rxjava2
Rxjava2 Android Samples
RxJava 2 Android Examples - Migration From RxJava 1 to RxJava 2 - How to use RxJava 2 in Android
Stars: ✭ 4,950 (+723.63%)
Mutual labels:  rxjava, rxjava2
Rxretrojsoup
A simple API-like from html website (scrapper) for Android, RxJava2 ready !
Stars: ✭ 492 (-18.14%)
Mutual labels:  rxjava, rxjava2
Grox
Grox helps to maintain the state of Java / Android apps.
Stars: ✭ 336 (-44.09%)
Mutual labels:  rxjava, rxjava2
Fast Android Networking
🚀 A Complete Fast Android Networking Library that also supports HTTP/2 🚀
Stars: ✭ 5,346 (+789.52%)
Mutual labels:  rxjava, rxjava2
Rxbus
🚌 The RxBus as steady as an old dog.
Stars: ✭ 334 (-44.43%)
Mutual labels:  rxjava, rxjava2
Bugsnag React Native
Error monitoring and reporting tool for native exceptions and JS errors in React Native apps
Stars: ✭ 374 (-37.77%)
Mutual labels:  error-handling, error-reporting
Apollo
🚀 Awesome EventBus by RxJava.
Stars: ✭ 329 (-45.26%)
Mutual labels:  rxjava, rxjava2
Rxbluetooth
Android reactive bluetooth
Stars: ✭ 405 (-32.61%)
Mutual labels:  rxjava, rxjava2
Rxgps
Finding current location cannot be easier on Android !
Stars: ✭ 307 (-48.92%)
Mutual labels:  rxjava, rxjava2
Swipe
👉 detects swipe events on Android
Stars: ✭ 324 (-46.09%)
Mutual labels:  rxjava, rxjava2
Bugsnag Php
Bugsnag error monitoring and crash reporting tool for PHP apps
Stars: ✭ 475 (-20.97%)
Mutual labels:  error-handling, error-reporting
Rxfirebase
Rxjava 2.0 wrapper on Google's Android Firebase library.
Stars: ✭ 509 (-15.31%)
Mutual labels:  rxjava, rxjava2

RxDogTag

RxDogTag is a utility to tag originating subscribe points in RxJava 2+ observers, with the goal of surfacing their subscribe locations for error reporting/investigation later in the event of an unhandled error. This is only for RxJava observers that do not implement onError().

Download

If you're targeting RxJava 2:

Maven Central

implementation("com.uber.rxdogtag:rxdogtag:x.y.z")

If you're targeting RxJava 3:

Maven Central

implementation("com.uber.rxdogtag2:rxdogtag:x.y.z")

Setup

Install early in your application lifecycle via RxDogTag.install(). This will install the necessary hooks in RxJavaPlugins. Note that these will replace any existing plugins at the hooks it uses. See the JavaDoc for full details of which plugins it uses.

Example

Consider the following classic RxJava error:

Observable.range(0, 10)
    .subscribeOn(Schedulers.io())
    .map(i -> null)
    .subscribe();

This is a fairly common case in RxJava concurrency. Without tagging, this yields the following trace:

io.reactivex.exceptions.OnErrorNotImplementedException: The exception was not handled due to missing onError handler in the subscribe() method call. Further reading: https://github.com/ReactiveX/RxJava/wiki/Error-Handling | The mapper function returned a null value.
	at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
	at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
	at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:77)
	at io.reactivex.internal.observers.BasicFuseableObserver.onError(BasicFuseableObserver.java:100)
	at io.reactivex.internal.observers.BasicFuseableObserver.fail(BasicFuseableObserver.java:110)
	at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:59)
	at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
	at io.reactivex.internal.operators.observable.ObservableScalarXMap$ScalarDisposable.run(ObservableScalarXMap.java:248)
	at io.reactivex.internal.operators.observable.ObservableJust.subscribeActual(ObservableJust.java:35)
	at io.reactivex.Observable.subscribe(Observable.java:12090)
	at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
	at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)
	at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
	at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: The mapper function returned a null value.
	at io.reactivex.internal.functions.ObjectHelper.requireNonNull(ObjectHelper.java:39)
	at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:57)
	... 14 more

This is basically impossible to investigate if you're looking at a crash report from the wild.

Now the same error with RxDogTag enabled:

io.reactivex.exceptions.OnErrorNotImplementedException: The mapper function returned a null value.

Caused by: java.lang.NullPointerException: The mapper function returned a null value.
	at anotherpackage.ReadMeExample.complex(ReadMeExample.java:55)
	at [[ ↑↑ Inferred subscribe point ↑↑ ]].(:0)
	at [[ ↓↓ Original trace ↓↓ ]].(:0)
	at io.reactivex.internal.functions.ObjectHelper.requireNonNull(ObjectHelper.java:39)
	at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:57)
	at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
	at io.reactivex.internal.operators.observable.ObservableScalarXMap$ScalarDisposable.run(ObservableScalarXMap.java:248)
	at io.reactivex.internal.operators.observable.ObservableJust.subscribeActual(ObservableJust.java:35)
	at io.reactivex.Observable.subscribe(Observable.java:12090)
	at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
	at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)
	at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
	at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

Now we have the example subscribe line at ReadMeExample.java:55. It may not be a silver bullet to root-causing why the exception occurred, but at least you know where it's emanating from.

The subscribe line reported should also retrace and group well for crash reporting. As we use our own in-house reporter though, we're very open to feedback on how this can be improved for other solutions.

More examples and details can be found in the wiki

Configuration

RxDogTag has an alternative RxDogTag.builder() API to facilitate added configuration, such as annotation control, stacktrace element location, and more.

Custom handlers

In the event of custom observers that possibly decorate other observer types, this information can be passed to RxDogTag via the ObserverHandler interface. This interface can be used to unwrap these custom observers to reveal their delegates and their potential behavior. Install these via the RxDogTag.Builder#addObserverHandlers(...) overloads that accept handlers.

Ignored packages

RxDogTag needs to ignore certain packages (such as its own or RxJava's) when inspecting stack traces to deduce the subscribe point. You can add other custom ones via RxDogTag.Builder#addIgnoredPackages(...).

AutoDispose support

AutoDispose is a library for automatically disposing streams, and works via its own decorating observers under the hood. AutoDispose can work with RxDogTag via its delegateObserver() APIs on the AutoDisposingObserver interfaces. Support for this is available via separate rxdogtag-autodispose artifact and its AutoDisposeObserverHandler singleton instance.

RxDogTag.builder()
    .configureWith(AutoDisposeConfigurer::configure)
    .install();

If you're targeting RxJava 2:

Maven Central

implementation("com.uber.rxdogtag:rxdogtag-autodispose:x.y.z")

If you're targeting RxJava 3:

Maven Central

implementation("com.uber.rxdogtag2:rxdogtag-autodispose:x.y.z")

Development

Javadocs for the most recent release can be found here: https://uber.github.io/RxDogTag/0.x/rxdogtag/com.uber.rxdogtag/

Snapshots of the development version are available in Sonatype's snapshots repository.

License

Copyright (C) 2019 Uber Technologies

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.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].