Reputation: 2861
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
?
Upvotes: 1
Views: 207
Reputation: 271420
The problem is this line:
Result.Success(response.body())
body
is marked with Nullable
, so when ported to Kotlin, response.body()
returns a T?
, rather than T
. See here for how this works.
Therefore, the type parameter for Result.Success
is inferred to be T?
, and so the expression above creates a Result<T?>
. Note that the T
in Result<T?>
refers to the type parameter of request
.
Upvotes: 1