Since this looks like Kotlin, worth pointing out that there is a kotlin class in the standard library called Result. I've been using that for a few things. One place that I'm on the fence about but that seems to work well for us is using this in API clients.
We have a pretty standard Spring Boot server with the usual reactive kotlin suspend controllers. Our api client is different. We were early adopters of kotlin-js on our frontend. Not something I necessarily recommend but through circumstances it was the right choice for us and it has worked well for us in the last five years. But it was a rough ride especially the first three of those.
As a consequence, our API client is multiplatform. For every API endpoint, there's a suspend function in the client library. And it returns a Result<T> where T is the deserialized object (via kotlinx serialization, which is multiplatform).
On the client side, consuming a result object is similar to dealing with promises. It even has a fold function that takes a success and error block. Basically failures fall into three groups: 1) failures (any 4xx code) that probably indicate client side bugs related to validation or things that at least need to be handled (show a message to the user), 2) internal server errors (500) that need to be fixed on the server, and 3) intermittent failures (e.g. 502, 503) which usually means: wait, try again, and hope the problem goes away.
What I like about Result is making the error handling explicit. But it feels a bit weird to client side construct an Exception only to stuff it into a Result.error(...) instead of actually throwing it. IMHO there's a bit of language friction there. I also haven't seen too many public APIs that use Result. But that being said, our multiplatform client works well for our use.
But I can't expose it to Javascript in its current form; which is something I have been considering to do. This is possible with special annotations and would mean our multiplatform client would be usable in normal react/typescript projects and something I could push as an npm. But the fact my functions return a Result makes that a bit awkward. Which is why I'm on the fence about using it a lot.
So, nice as a Kotlin API but good to be aware of portability limitations like that. You would have similar issues exposing Kotlin code like that to Java.
> But it feels a bit weird to client side construct an Exception only to stuff it into a Result.error(...) instead of actually throwing it
yep, `kotlin.Result` constraining your error type to `Throwable` is a real headache as it forces you to still model your domain logic via exceptions. it also means people can still accidentally throw these exceptions. not to mention the overhead of creating stack traces per instantiation unless you disable that on every subclass.
i recommend using https://github.com/michaelbull/kotlin-result?tab=readme-ov-f... (which has a nice breakdown of all the other reasons to avoid `kotlin.Result`)
ArrowKt is also worth a mention: https://arrow-kt.io/learn/typed-errors/
Thank you, a very insightful comment :) As a side note, my latest post (on the same website) is on "reactive" Java / suspend functions in Kotlin.