A generic class for holding network request result
sealed class Result<out T : Any?> {
data class Success<out T : Any?>(val data: T) : Result<T>()
data class Error(val message: String, val exception: Exception? = null) : Result<Nothing>()
}
A generic function for encapsulating network result into Result.
It is called from a repository and passes a retrofit2 api call as an input parameter
suspend fun <T: Any?> request(method: Call<T>): Result<T> {
return withContext(Dispatchers.IO) {
try {
val response = method.awaitResponse() // Retrofit2 Call
if (response.isSuccessful)
Result.Success(response.body())
else
response.getErrorResult()
} catch (e: Exception) {
Result.Error(e.message.orEmpty(), e)
}
}
// Type mismatch.
// Required: Result<T>
// Found: Result<T?>
}
It is called like this
interface Webservice {
@GET("data")
fun getData(): Call<Data> // Retrofit2
}
suspend fun getData(): Result<Data> {
return request(webservice.getData())
}
Why does it infer the result as type T? but not T?
The problem is this line:
bodyis marked withNullable, so when ported to Kotlin,response.body()returns aT?, rather thanT. See here for how this works.Therefore, the type parameter for
Result.Successis inferred to beT?, and so the expression above creates aResult<T?>. Note that theTinResult<T?>refers to the type parameter ofrequest.