Skip to content

Instantly share code, notes, and snippets.

@lukaszkalnik
Created June 18, 2020 15:52
Show Gist options
  • Save lukaszkalnik/bdc9490d6cd5a0e4d3dbf9014626f488 to your computer and use it in GitHub Desktop.
Save lukaszkalnik/bdc9490d6cd5a0e4d3dbf9014626f488 to your computer and use it in GitHub Desktop.
private class EitherCall<R>(
private val delegate: Call<R>,
private val successType: Type
) : Call<Either<ApiError, R>> {
override fun enqueue(callback: Callback<Either<ApiError, R>>) = delegate.enqueue(
object : Callback<R> {
override fun onResponse(call: Call<R>, response: Response<R>) {
callback.onResponse(this@EitherCall, Response.success(response.toEither()))
}
private fun Response<R>.toEither(): Either<ApiError, R> {
// Http error response (4xx - 5xx)
if (!isSuccessful) {
val errorBody = errorBody()?.string() ?: ""
return Left(HttpError(code(), errorBody))
}
// Http success response with body
body()?.let { body -> return Right(body) }
// if we defined Unit as success type it means we expected no response body
// e.g. in case of 204 No Content
return if (successType == Unit::class.java) {
@Suppress("UNCHECKED_CAST")
Right(Unit) as Either<ApiError, R>
} else {
@Suppress("UNCHECKED_CAST")
Left(UnknownError("Response body was null")) as Either<ApiError, R>
}
}
override fun onFailure(call: Call<R>, throwable: Throwable) {
val error = when (throwable) {
is IOException -> NetworkError(throwable)
else -> UnknownApiError(throwable)
}
callback.onResponse(this@EitherCall, Response.success(Left(error)))
}
}
)
// override remaining methods - trivial
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment