Retrofit passing in suspend function

from the CommonsWare Community archives

At November 27, 2020, 5:51pm, Jan asked:

I am trying to centralize the try{} catch{} and error handling when making retrofit API calls. Examples on the internet have a safeAPICall function that would be something like this:
class APICall {
suspend fun safeApiCall(serviceCall: suspend () -> Response): APIResult {
return try {
val response = serviceCall()
or ------
//val response = serviceCall.invoke()
if (response.isSuccessful()) {

        } else {
    } catch (t: Throwable) {
        APIResult.Error("General failure")
} // safeApiCall

The problem I ran into was calling this function. I get the error message

Type mismatch.
suspend () → Response<TypeVariable(T)>

I tried two methods of calling and they both gave this error message:
val netService = // call retrofit create on (

The SigninRequest API is the normal Interface used with retrofit.

the examples in medium articles showing safeApiCall seemed to be just passing the function so I don’t understand what is going wrong here.

At November 27, 2020, 6:55pm, mmurphy replied:

suspend fun safeApiCall(serviceCall: suspend () -> Response) : APIResult

This would be called as:

safeApiCall {
  TODO("do something that returns a Response")

At November 27, 2020, 7:07pm, Jan replied:

Hmm. So I put in the retrofit call inside the body of the curly braces and returned Retrofit’s response. Unfortunately, that didn’t compile either.
I guess safeAPICall is just not intended to be used except for really complex situations like in all the examples I saw in the medium articles.
I tried the call back adapter method which all the articles said would work but that wouldn’t parse my json. At this point I could have coded the try/catches everywhere instead of making the solution elegant. :slight_smile:

At November 27, 2020, 7:22pm, mmurphy replied:

Another possibility is to use existing solutions for this sort of “convert the exceptions into dedicated classes”, such as

At November 27, 2020, 7:31pm, Jan replied:

I tried EitherNet but it’s definitely not ready. I got a compile error just adding it in.
I tried this one: which looked very promising. But it doesn’t parse out the JSON on a successful response body. Instead it returns the Unknown Error in the onFailure callback.