Suspend functions generic form

Viewed 78

I am using suspend functions in my repository, every function has try catch block and the code is duplicates.

For example:

class ApiRepository(private val api: Api) {

    suspend fun listAllProducts(): Response<List<Product>> {
        return try {
            val response = api.listAllProducts()
            Response.Success(Mapper.toProductList(response))
        } catch (e: Exception) {
            e.printStackTrace()
            Response.Error(e)
        }
    }

    suspend fun listAllProductCategories(): Response<List<Category>> {
        return try {
            val response = api.listAllProductCategories()
            Response.Success(Mapper.toCategoryList(response))
        } catch (e: Exception) {
            e.printStackTrace()
            Response.Error(e)
        }
    }
}

Response class

sealed class Response<T> {
    data class Success<T>(val value: T) : Response<T>()
    data class Error<T>(val t: Throwable) : Response<T>()
}

Is there more generic way to do it?

1 Answers

A higher order function like this could be used:

inline fun <T> getResponse(block: ()->T): Response<T> {
    return try {
        Response.Success(block())
    } catch (e: Exception) {
        e.printStackTrace()
        Response.Error(e)
    }
}

Then use it like this:

class ApiRepository(private val api: Api) {

    suspend fun listAllProducts(): Response<List<Product>> = getResponse {
        Mapper.toProductList(api.listAllProducts())
    }

    suspend fun listAllProductCategories(): Response<List<Category>> = getResponse {
        Mapper.toCategoryList(api.listAllProductCategories())
    }
}

It doesn't matter that your functions are suspend functions if getResponse is inline.

Related