Skip to content

Instantly share code, notes, and snippets.

@scottschmitz
Created February 25, 2020 20:04
Show Gist options
  • Save scottschmitz/e85106c812193b2949956d5346924b29 to your computer and use it in GitHub Desktop.
Save scottschmitz/e85106c812193b2949956d5346924b29 to your computer and use it in GitHub Desktop.
Safety Wrapper for Single.zip
sealed class SafeResult<T> {
class Success<T>(val result: T) : SafeResult<T>()
class Failure<T>(val error: Throwable) : SafeResult<T>()
}
import io.reactivex.Single
import io.reactivex.exceptions.CompositeException
/**
* Zip [Single] together safely. An onErrorReturn is automatically applied to each source
* to prevent any source from throwing. Then after all sources have completed, any errors
* are then reported
*/
fun <T> zipSafe(sources: List<Single<T>>): Single<List<T>> {
val safeSources = sources.map { source ->
source
.map<SafeResult<T>> { SafeResult.Success(it) }
.onErrorReturn { SafeResult.Failure(it) }
}
return Single.zip(safeSources) { it.filterIsInstance<SafeResult<T>>() }
.flatMap<List<T>> { safeResults ->
val failures = safeResults.filterIsInstance<SafeResult.Failure<T>>()
if (failures.isNotEmpty()) {
Single.error(CompositeException(failures.map { it.error }))
} else {
Single.just(
safeResults.map { (it as SafeResult.Success<T>).result }
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment