'How to Parse Kotlin Units with Moshi

I'm using retrofit for web requests and then moshi for JSON parsing,this is api

@POST("/verify_code/send_email")
    suspend fun sendEmail(@Body sendEmailRequest: SendEmailRequest): BaseResponse<Unit>

the BaseResponse

@JsonClass(generateAdapter = true)
open class BaseResponse<T> {

    @Json(name = "code")
    var code: Int? = null

    @Json(name = "message")
    var message: String? = null

    @Json(name = "data")
    var data: T? = null
}

JSON String

{
  "code": 200,
  "message": "Some Message",
  "data": null
}

and error log

2021-11-26 09:59:24.166 14288-14288/com.gow E/FlowKtxKt$next: java.lang.IllegalArgumentException: Unable to create converter for com.gow.base.BaseResponse<kotlin.Unit>
        for method VerifyApi.sendEmail

I tried adding the following, but it didn't work

object UnitConverterFactory : Converter.Factory() {
    override fun responseBodyConverter(
        type: Type, annotations: Array<out Annotation>,
        retrofit: Retrofit
    ): Converter<ResponseBody, *>? {
        return if (type == Unit::class.java) UnitConverter else null
    }

    private object UnitConverter : Converter<ResponseBody, Unit> {
        override fun convert(value: ResponseBody) {
            value.close()
        }
    }
}


Solution 1:[1]

it`s the Moshi bug.

I solved my problem by using Any instead of Unit.

like this:

@POST("/verify_code/send_email")
    suspend fun sendEmail(@Body sendEmailRequest: SendEmailRequest): BaseResponse<Any>

Solution 2:[2]

I had the same issue.

I fixed it by following the comment on this link.

I do not see how you are adding your UnitConverterFactory but in my case, the order you add it is important.

I am also using MoshiConverterFactory and ApiResultConverterFactory from EitherNet, so my UnitConverterFactory had to be placed after ApiResultConverterFactory and before MoshiConverterFactory:

Retrofit.Builder()
  ...
  .addCallAdapterFactory(ApiResultCallAdapterFactory)
  //the order of the converters matters.
  .addConverterFactory(ApiResultConverterFactory)
  .addConverterFactory(UnitConverterFactory)
  .addConverterFactory(MoshiConverterFactory.create(moshi))
  .build()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sana Ebadi
Solution 2 Leandro Ocampo