skydoves / sandwich

🥪 Sandwich is an adaptable and lightweight sealed API library designed for handling API responses and exceptions in Kotlin for Retrofit, Ktor, and Kotlin Multiplatform.
https://skydoves.github.io/sandwich/
Apache License 2.0
1.57k stars 101 forks source link

java.lang.RuntimeException: Failed to invoke private com.skydoves.sandwich.ApiResponse() with no args #29

Closed JosephSanjaya closed 3 years ago

JosephSanjaya commented 3 years ago

Please complete the following information:

Describe the Bug: image response that used Sandwich always failed, with exception like above

Expected Behavior: Response should be success because implementation without Sandwich had no problem

Implementation:

@GET("api/v3/rekening/detail")
    suspend fun getRekeningDetail(
        @Header("Authorization") auth: String,
        @Query("id") id: String,
        @Query("type") type: String
    ): ApiResponse<ResponseResult<Rekening>>

data class ResponseResult<T>(
    @field:SerializedName("data")
    val data: T? = null,

    @field:SerializedName("message")
    val message: String? = null,

    @field:SerializedName("status")
    val status: Int? = null
)

fun getRekeningById(rekeningId: String, rekeningType: RekeningType) = flow {
        emit(State.Single.Loading())
        var rekeningData: Rekening? = null
        if (NetworkUtils.isConnected()) {
            val response =
                service.getRekeningDetail(
                    mSecuredPreferences.accessToken,
                    rekeningId,
                    rekeningType.value
                )
            response.suspendOnSuccess {
                dao.insertSyncData(listOf(data.data))
                rekeningData = dao.getRekeningById(rekeningId)
            }.suspendOnError {
                rekeningData = dao.getRekeningById(rekeningId)
            }.suspendOnException {
                rekeningData = dao.getRekeningById(rekeningId)
            }
        } else {
            rekeningData = dao.getRekeningById(rekeningId)
        }
        emit(State.Single.Success(rekeningData))
    }.flowOn(Dispatchers.IO)
skydoves commented 3 years ago

Hi, Could you share your Retrofit Builder?

skydoves commented 3 years ago

If you don't use the CoroutinesResponseCallAdapterFactory or use it with another factory, RuntimeException will happen.

JosephSanjaya commented 3 years ago

this is my retrofit builder

val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl(Secured.getBaseUrlApi(isBareksa))
        .client(okHttpClient)
        .addCallAdapterFactory(CoroutineCallAdapterFactory())
        .addConverterFactory(ScalarsConverterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build()

ooh, I think this is the problem I thought it was the same as CoroutineCallAdapterFactory

JosephSanjaya commented 3 years ago

Sorry, my bad it's fixed now

Thank you for fast response