I followed this guide and found this question for handling network exceptions with Retrofit. While they both are very useful, none of them explain how to extract the body of a successful request. Here is a snippet of code that might better explain what I'm trying to accomplish:
The sealed class remains the same from both examples...
// exception handling:
sealed class NetworkResponse<out T : Any, out U : Any> {
data class Success<T : Any>(val body: T) : NetworkResponse<T, Nothing>()
data class ApiError<U : Any>(val body: U, val code: Int) : NetworkResponse<Nothing, U>()
data class NetworkError(val error: IOException) : NetworkResponse<Nothing, Nothing>()
data class UnknownError(val error: Throwable) : NetworkResponse<Nothing, Nothing>()
}
but extracting the body on a successful call is unclear to me. Here is my attempt:
val oAuthRetrofit: Retrofit = Retrofit.Builder()
.baseUrl(OAUTH_BASE_URL)
.addConverterFactory(Json.asConverterFactory(contentType))
.build()
val salesforceOAuthAPI: SalesforceInterface =
oAuthRetrofit.create(SalesforceInterface::class.java)
val oAuthAccessTokenResponse: NetworkResponse<OAuthAccessTokenResponse, Error> =
salesforceOAuthAPI.getOAuthAccessToken(
GRANT_TYPE,
BuildConfig.SALESFORCE_CLIENT_ID,
BuildConfig.SALESFORCE_CLIENT_SECRET,
BuildConfig.SALESFORCE_USERNAME,
BuildConfig.SALESFORCE_PASSWORD + BuildConfig.SALESFORCE_SECURITY_TOKEN
)
val body = oAuthAccessTokenResponse.body // Unresolved reference
// Use body()
How can I extract the body of a successful request?
In the medium post you have access to the Source Code
there you can check what you missing.
Answering your question
How can I extract the body of a successful request?
You can simply do this :
val response1 = salesforceOAuthAPI.getWhatever()
when (response1) {
is NetworkResponse.Success -> Log.d(TAG, "Success ${response1.body.name}")
is NetworkResponse.ApiError -> Log.d(TAG, "ApiError ${response1.body.message}")
is NetworkResponse.NetworkError -> Log.d(TAG, "NetworkError")
is NetworkResponse.UnknownError -> Log.d(TAG, "UnknownError")
}
And in the NetworkResponse.Success
you have the data you want, but since you are using a sealed class
to detect the error and the data, you don't know what is inside that object until you do a when
.
By the way, don't know if you followed all the post but you missing the
.addCallAdapterFactory(NetworkResponseAdapterFactory())
In the Retrofit.Builder()
otherwise it won't do the magic to encapsulate everything to a NetworkResponse