Hi all. Shall I create my own general purpose `Res...
# getting-started
g
Hi all. Shall I create my own general purpose `Result`:
Success
or
Failure
type hierarchy or should I use some library for that?
a
g
I find it a bit stiffling that the failure is represented as an exception. I just want to put a message.
2
But maybe its actually a good thing, I can check error types.
But I think I saw that that
Result
is for internal usage.
j
https://github.com/Kotlin/KEEP/blob/master/proposals/stdlib/result.md#error-handling-style-and-exceptions > The
Result
class is not designed to represent domain-specific error conditions.
g
indeed
I was looking into either write myself something or use libraries
I don’t want to create a different
Result
type for every function
j
My reading of that section is, that in most cases there is no need for a
Result
class because: if you want a generic response representing failure -> use null else -> you need a domain specific response and the result class won’t help you anyways. Instead create your own domain specific result
1
p
The problem is that there is not a single library with just that. You will probably ended up bringing a lot of other things you won't use. So yes have your own better. The kotlin result is not designed for domain layer errors but for system errors, that is why is based on exceptions.
y
Arrow's Either, or even better, Arrow's Raise, is definitely the way to go for error-handling
c
Arrow is exactly for this. They add a few utilities for combining failed results of different types, and they are currently reducing their API as much as possible to be easy to integrate in projects. See #arrow and https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/
👍 2
g
@Jacob how can null represent failure? I would at least want a string saying something about why error happened. The function being called knows why, so I want it to return that.
@CLOVIS I looked at arrow - have some issues making it work from java. I have a mixed java/kotlin project. But to be honest, It’s literally 4 lines of code:
Copy code
sealed interface Result<T, R> {
    class Success<T, R>(val value: T): Result<T, R>
    class Failure<T, R>(val error: R): Result<T, R>
}
s
If those 4 lines are all that you need then go for it! However i find myself using the conveniently added functions a lot, for example .map{} .bind() etc. Which is why people probably recommend arrow. An alternative might be https://github.com/fork-handles/forkhandles/tree/trunk/result4k
👍 1
j
@Gasan null can represent failure since usually you don't need to know why something failed There's usually a very limited set of reasons ie. the toIntornull function on all strings, usually returns null for non numeric strings. In the case that you do need to know why something failed, a stringly typed field isn't much help except in the rare case that we can return that string directly to the user. If you want to handle different failures differently progromatically, you'll need a custom result.
s
c
But to be honest, It’s literally 4 lines of code:
Yes, it is. And if that's all you need, great! But as soon as you start calling two functions which return
Result
and want to return a successful value if both are successful, etc, you will want
map
,
flatMap
,
zip
… At that point, it quickly becomes worth using Arrow rather than rewrite everything
m
@Gasan Kotlin error handling is quite broad and can be a rather deep topic.. I've written a survey article on typed error handling comparing their pros/cons. What @CLOVIS eluded to is when logic grows, the ergonomic improvements in Arrow will really help code maintainers. https://betterprogramming.pub/typed-error-handling-in-kotlin-11ff25882880
c
@mitch that article is a really good explanation of the different ways of doing it!
🙇 1