i

    Igor Milakovic

    7 months ago
    How do you guys handle errors in KMM? For example, I have this use case
    interface SignInUseCase {
        @Throws(Exception::class)
        suspend fun execute(email: String, password: String): Whatever
    }
    When I call this from iOS, I get
    signInUseCase.execute(email: email, password: password) { whatever, error in
        // Handle completion
    }
    Is there a way to have a custom error here, instead of NSError? Ideally, I'd like to have maybe a class or data class
    data class Error(
        val title: String
        val detail: String
    }
    Tim Oltjenbruns

    Tim Oltjenbruns

    7 months ago
    ooh good question
    I would consider using a sealed class here for the return value to represent success and failure.
    the NSError you get in the completion needs to stay generic because theoretically any throwable could be thrown. (regardless of using @Throws or not)
    i

    Igor Milakovic

    7 months ago
    Yeah, I was thinking about that too. So I just have to live with potentially handling two errors? 🙂
    I mean, one from the Result.Failure and one from potentially thrown Exception
    Tim Oltjenbruns

    Tim Oltjenbruns

    7 months ago
    So I’m assuming you are dealing with some high level business logic here due to the “Use Case” naming convention
    I don’t think it’s appropriate to throw any exceptions from there
    So in that case the only exception you would get in your completion is either cancellation or something unexpected
    i

    Igor Milakovic

    7 months ago
    Correct, but I'm just trying out the interface being used from iOS and Android native apps, to see how I can provide only what I needed
    Yeah, for example, I'm getting the exception from Ktor when sign in fails
    So I guess it's because I'm not handling it, just passing it down all the way from HttpClient
    Tim Oltjenbruns

    Tim Oltjenbruns

    7 months ago
    Right! and then from your testing you identify that case and catch it somewhere closer to where it’s thrown
    then encode that into your result, because its relevant to the business of the use case
    i

    Igor Milakovic

    7 months ago
    Gotcha, so I should parse it as soon as it exits the HttpClient domain and then pass the Result all the way down
    Tim Oltjenbruns

    Tim Oltjenbruns

    7 months ago
    Yes, I would do that in this case.
    i

    Igor Milakovic

    7 months ago
    Thank you very much Tim, this was super helpful!
    Tim Oltjenbruns

    Tim Oltjenbruns

    7 months ago
    Some cases I would not trickle from HTTP into the business layer though, for example if there was a socket disconnect error.
    i

    Igor Milakovic

    7 months ago
    Just one bonus question - does it make sense to try and use Kotlin's result or I'm better off with just having a custom sealed class?
    Tim Oltjenbruns

    Tim Oltjenbruns

    7 months ago
    I would suggest another sealed class, because Kotlin’s is semi-reserved
    it’s used internally for coroutines
    i

    Igor Milakovic

    7 months ago
    Yeah, I had some weird issues on iOS side, when using the Kotlin Result
    Again, thank you very much for your help!
    Wish there were some karma or friendship points to award to you 🙂
    Tim Oltjenbruns

    Tim Oltjenbruns

    7 months ago
    Socket disconnect I might handle and trickle through as a cancel of the coroutine. That one does not go into the result, but it comes through as an exception. I like this, because I don’t want my high level business logic to worry about low-level network issues. Just auth errors.
    The smile is plenty 🙂
    perhaps you find it useful 🙂
    i

    Igor Milakovic

    7 months ago
    Hi Guilherme! Thanks for the link, I actually ran into that one, but I can't use Future, as I'm still supporting iOS 12 😞 However, I'll read it again and see if I can parse the sealed class regardless. It's driving me nuts at the moment 🤯