Skip to content

Instantly share code, notes, and snippets.

@mukandrew
Last active February 7, 2022 19:07
Show Gist options
  • Save mukandrew/869d86dfa236849602ffa4f7c60e2022 to your computer and use it in GitHub Desktop.
Save mukandrew/869d86dfa236849602ffa4f7c60e2022 to your computer and use it in GitHub Desktop.
Android-KT: Files with common response file and extension to throw the exception
internal suspend fun <T> runCatchingNetworkException(block: suspend () -> T): T {
return try {
block()
} catch (e: HttpException) {
val response = e.response()
throw NetworkException(
response?.code(),
response?.message(),
response?.errorBody()?.charStream()?.readText()?.replace("\"", "")
)
}
}
internal suspend fun <T : Any> runCatchingResponse(
blockCatchNetwork: (suspend (e: NetworkException) -> Exception)? = null,
blockCatch: (suspend (e: Exception) -> Exception)? = null,
blockTry: suspend () -> T
): Response<T> {
return try {
Response.of(blockTry())
} catch (e: NetworkException) {
val exception = blockCatchNetwork?.invoke(e) ?: e
// Do something with the exception, changing to a unique exception to identify, also logging in the Analytics
Response.of(exception)
} catch (e: Exception) {
val exception = blockCatch?.invoke(e) ?: e
// Do something with the exception, changing to a unique exception to identify, also logging in the Analytics
Response.of(exception)
}
}
class ViewModel(private val useCase: UseCase) {
fun doSomething() {
when(val response = useCase.doSomething()) {
is Success -> TODO()
is Failure -> TODO()
}
}
}
data class DomainModel(val foo: String)
class UseCase(private val repository: Repository) {
suspend operator fun invoke(): Response<DomainModel> {
when(val response = repository.doSomething()) {
is Success -> TODO()
is Failure -> TODO()
}
}
}
class Repository(private val dataSource: DataSource) {
suspend fun doSomething(): Response<DomainModel> {
return runCatchingResponse {
DomainModel(foo = dataSource.doSomething().foo)
}
}
}
data class NetworkModel(val foo: String)
class DataSource(private val api: API) {
suspend fun doSomething(): NetworkModel {
return runCatchingNetworkException { api.doSomething() }
}
}
// RETROFIT REST INTERFACE
interface API {
@GET("/do-something")
suspend fun doSomething(): NetworkModel
}
internal class NetworkException(
val status: Int?,
val httpMessage: String? = null,
override val message: String?,
) : Exception()
sealed interface Response<out T : Any> {
data class Success<T : Any>(val data: T) : Response<T>
data class Failure(val exception: Exception) : Response<Nothing>
companion object {
fun <T : Any> of(data: T): Response<T> {
return Success(data)
}
fun <T : Any> of(exception: Exception): Response<T> {
return Failure(exception)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment