Skip to content

Instantly share code, notes, and snippets.

@fullkomnun
Created February 6, 2018 10:17
Show Gist options
  • Save fullkomnun/503234752b332acb0b1d19efd7fe8c5e to your computer and use it in GitHub Desktop.
Save fullkomnun/503234752b332acb0b1d19efd7fe8c5e to your computer and use it in GitHub Desktop.
Wraps retrofit reactive calls so that retrofit errors can be traced back to client code that invoked the operation
class RxErrorHandlingCallAdapterFactory private constructor(private val original: RxJava2CallAdapterFactory) : CallAdapter.Factory() {
override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *>? =
original.get(returnType, annotations, retrofit)?.let {
RxCallAdapterWrapper(it as CallAdapter<Any, Any>)
}
private class RxCallAdapterWrapper(private val wrapped: CallAdapter<Any, Any>) : CallAdapter<Any, Any> by wrapped {
override fun adapt(call: Call<Any>): Any {
val adaptedCall = wrapped.adapt(call)
return when (adaptedCall) {
is Completable -> adaptedCall.dropBreadcrumb()
is Single<*> -> adaptedCall.dropBreadcrumb()
is Maybe<*> -> adaptedCall.dropBreadcrumb()
is Flowable<*> -> adaptedCall.dropBreadcrumb()
is Observable<*> -> adaptedCall.dropBreadcrumb()
else -> throw RuntimeException("Observable Type not supported")
}
}
}
companion object {
fun create(original: RxJava2CallAdapterFactory): CallAdapter.Factory =
RxErrorHandlingCallAdapterFactory(original)
}
}
fun Completable.dropBreadcrumb(): Completable {
val breadcrumb = BreadcrumbException()
return this.onErrorResumeNext { error: Throwable ->
throw CompositeException(error, breadcrumb)
}
}
fun <T> Single<T>.dropBreadcrumb(): Single<T> {
val breadcrumb = BreadcrumbException()
return this.onErrorResumeNext { error: Throwable ->
throw CompositeException(error, breadcrumb)
}
}
fun <T> Maybe<T>.dropBreadcrumb(): Maybe<T> {
val breadcrumb = BreadcrumbException()
return this.onErrorResumeNext { error: Throwable ->
throw CompositeException(error, breadcrumb)
}
}
fun <T> Flowable<T>.dropBreadcrumb(): Flowable<T> {
val breadcrumb = BreadcrumbException()
return this.onErrorResumeNext { error: Throwable ->
throw CompositeException(error, breadcrumb)
}
}
fun <T> Observable<T>.dropBreadcrumb(): Observable<T> {
val breadcrumb = BreadcrumbException()
return this.onErrorResumeNext { error: Throwable ->
throw CompositeException(error, breadcrumb)
}
}
// see: https://en.wikipedia.org/wiki/Hansel_and_Gretel
class BreadcrumbException : Exception()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment