본문 바로가기

Android

RxDogTag - RxJava 오류 시, 스택 트레이스를 알아보기 쉽게

https://github.com/uber/RxDogTag

 

uber/RxDogTag

Automatic tagging of RxJava 2 originating subscribe points for onError() investigation. - uber/RxDogTag

github.com

 

Uber에서 RxDogTag 을 출시했습니다.

 

RxJava를 쓰다가 에러가 발생했을 때, 아래와 같이 알아보기 힘든 로그가 나옵니다.

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)
...

...
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

 

내가 작성한 코드가 어느 부분인지 표시되지 않고, 어느 라인에서 에러가 발생했는지 쉽게 알기 어렵습니다.

 

이런 알아보기 힘든 Rx 스택 트레이스를, RxDogTag는 이렇게 알아보기 쉽게 바꿔줍니다.

Caused by: java.lang.NullPointerException: The mapper function returned a null value.
at com.uber.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)

 

위 로그를 보면 ReadMeExample.java 의 55 라인에서 에러가 발생한 것을 정확하게 알 수 있습니다.