For legacy reasons I need to talk to API:s that re...
# ktor
n
For legacy reasons I need to talk to API:s that return both success and error body as http 200. How can i parse/approach that with ktor+kotlinx.serialization? If deserialization fails I get a
JsonConvertException
and not a
ResponseException
with the
HttpResponse
that I can parse into a different structure..
a
Can you share an example of both success and error responses?
n
Sure, I'm trying to achieve something like this; but it seems not to be possible since if
.body<ConsentResponse>
throws a
JsonConvertException
with cause
MissingFieldException
Copy code
/**
 *  {"errorCode": "42", "message": "something went wrong"}
 */
@Serializable
data class ErrorResponse(
    val errorCode: String,
    val message: String
)

/**
 *  {"hasGivenConsent": false}
 */
@Serializable
data class ConsentResponse(
    val hasGivenConsent: Boolean
)

sealed class Result<out T, out E> {
    data class Success<T>(val value: T) : Result<T, Nothing>()
    data class Failure<E>(val error: E) : Result<Nothing, E>()
}

fun main(): Unit = runBlocking {
    val client = HttpClient()

    val result: Result<ConsentResponse, ErrorResponse> = try {
        Result.Success(client.get("<https://example.com/v1/consent>").body<ConsentResponse>())
    } catch (e: ResponseException) {
        val errorResponse = e.response.body<ErrorResponse>()
        Result.Failure(errorResponse)
    }
    
    println("result: $result")
}
(I have many such cases with different success/error responses so im looking for a somewhat generic way of solving it)
a
You can write a custom serializer to delegate deserialization to either a success or an error serializer, depending on the shape of the JSON. Serializers for concrete success types can be registered in the serializer module. Here is a complete example:
client.kt.cpp
n
oh interesting, thank you very much Aleksei I'll take a look 🙏