https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
i

Igor Milakovic

02/15/2022, 10:33 PM
How do you guys handle errors in KMM? For example, I have this use case
Copy code
interface SignInUseCase {
    @Throws(Exception::class)
    suspend fun execute(email: String, password: String): Whatever
}
When I call this from iOS, I get
Copy code
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
Copy code
data class Error(
    val title: String
    val detail: String
}
t

Tim Oltjenbruns

02/15/2022, 11:00 PM
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

02/15/2022, 11:02 PM
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
t

Tim Oltjenbruns

02/15/2022, 11:03 PM
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

02/15/2022, 11:04 PM
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
t

Tim Oltjenbruns

02/15/2022, 11:05 PM
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

02/15/2022, 11:06 PM
Gotcha, so I should parse it as soon as it exits the HttpClient domain and then pass the Result all the way down
t

Tim Oltjenbruns

02/15/2022, 11:06 PM
Yes, I would do that in this case.
i

Igor Milakovic

02/15/2022, 11:06 PM
Thank you very much Tim, this was super helpful!
t

Tim Oltjenbruns

02/15/2022, 11:06 PM
Some cases I would not trickle from HTTP into the business layer though, for example if there was a socket disconnect error.
👍 1
i

Igor Milakovic

02/15/2022, 11:07 PM
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?
t

Tim Oltjenbruns

02/15/2022, 11:07 PM
I would suggest another sealed class, because Kotlin’s is semi-reserved
it’s used internally for coroutines
i

Igor Milakovic

02/15/2022, 11:08 PM
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 🙂
t

Tim Oltjenbruns

02/15/2022, 11:08 PM
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.
💯 1
The smile is plenty 🙂
❤️ 1
perhaps you find it useful 🙂
i

Igor Milakovic

02/16/2022, 4:25 PM
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 🤯
👍 1
529 Views