Tiago Nunes

    Tiago Nunes

    1 year ago
    In Retrofit we used a custom CallAdapter to wrap every response or error in a NetworkResponse sealed class, instead of relying on exceptions, after reading https://elizarov.medium.com/kotlin-and-exceptions-8062f589d07 by @elizarov. But in Ktor, every example of error handling (including in the documentation https://ktor.io/docs/response-validation.html#expect-success) uses Exceptions instead of Sealed classes. Should we catch the waves and throw ourselves back to exception handling or should we try to implement our own feature to wrap responses in a sealed class?
    k

    KamilH

    1 year ago
    Javier

    Javier

    1 year ago
    I tried to create a feature similar to the adapter for retrofit but I couldn't. So I finished getting something like:
    val response = networkEither { client.get("...") }
    Tiago Nunes

    Tiago Nunes

    1 year ago
    Something similar, with proceedWith in intercept
    Javier

    Javier

    1 year ago
    Please, if you get it working, can you share the link? 😉
    Tiago Nunes

    Tiago Nunes

    1 year ago
    Ofc 🙂
    Javier

    Javier

    1 year ago
    I tried following that feature but I don't remember what problem I had
    Mustafa Ozhan

    Mustafa Ozhan

    1 year ago
    maybe you are looking something like this ? I also catch the error in common and Wrap it with my custom Result sealed class.https://github.com/CurrencyConverterCalculator/CCC/blob/master/common/src/commonMa[…]/kotlin/com/github/mustafaozhan/ccc/common/api/ApiRepository.kt
    Tiago Nunes

    Tiago Nunes

    1 year ago
    Yes, I think it has to be something like that. I tried to implement a feature that wraps the response in a NetworkResponse sealed class. The problem was: 1. HttpClient.request() returns T 2. JsonFeature uses serializer for T Which means that if 1. I use get<Rocket>, I can't call proceedsWith with a NetworkResponse<Rocket>. 2. I use get<NetworkResponse<Rocket>>, there is a Serialization Exception, because it tries to deserialize the response to a NetworkResponse<Rocket>
    Only option I see would be to create "my own" JsonFeature, but that doesn't seem right
    Mustafa Ozhan

    Mustafa Ozhan

    1 year ago
    I have this
    sealed class Result<T> {
        data class Success<T>(val data: T) : Result<T>()
        data class Error(val exception: Throwable) : Result<Nothing>()
    
        fun execute(
            success: ((T) -> Unit)? = null,
            error: ((Throwable) -> Unit)? = null,
            complete: (() -> Unit)? = null
        ) {
            when (this) {
                is Success -> success?.invoke(data)
                is Error -> error?.invoke(exception)
            }
            complete?.invoke()
        }
    }
    and I use like this
    apiRepository
                .getRatesViaBackend(settingsRepository.currentBase)
                .execute(::getRatesSuccess, ::getRatesFailed)
    So i get rid of try catches, with this wrapper. Actual error mapping is inside the ApiRepository that I shared previously
    Tiago Nunes

    Tiago Nunes

    1 year ago
    Yes, I get it, you have a function that wraps the response and call it on every request. That was also a possibility in Retrofit, but CallAdapter was cleaner, if the type was NetworkResponse, it wrapped automatically, you wouldn't need to call a function explicitily
    It's still a clean enough solution, and I'll surely use it if I can't find another way, so thanks 🙂
    Mustafa Ozhan

    Mustafa Ozhan

    1 year ago
    You are welcome 🙂 If you find some out of the box solution just post here so i will have a look at it too 🙂
    Javier

    Javier

    1 year ago
    Yeah, that you are doing is the same I do with
    val response: NetworkEither<SomeError, SomeSuccess> = networkEither { client.get("...") }
    but as @Tiago Nunes said, a feature is cleaner like an adapter in retrofit.
    rudolf.hladik

    rudolf.hladik

    1 year ago
    you don’t need json feature, you can parse the response yourself and retype it to whatever you need. Just call
    httpClient.request<HttpResponse> {...}
    Tiago Nunes

    Tiago Nunes

    1 year ago
    I wouldn't want to parse every response everytime, I would prefer to create my own Json feature in that case
    Javier

    Javier

    1 year ago
    @Tiago Nunes did you get some advances?
    Tiago Nunes

    Tiago Nunes

    1 year ago
    Hey, no but I might get back to it later