# Result objects instead of exceptions

**URL:** <https://discuss.kotlinlang.org/t/result-objects-instead-of-exceptions/24548>\
**Category:** Uncategorized\
**Created:** [April 6, 2022, 9:59am UTC](https://discuss.kotlinlang.org/t/result-objects-instead-of-exceptions/24548 "2022-04-06T09:59:21Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![medium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/medium/32/10404_2.png) [@medium](https://discuss.kotlinlang.org/u/medium)\
**Post date:** [April 6, 2022, 9:59am UTC](https://discuss.kotlinlang.org/t/result-objects-instead-of-exceptions/24548/1 "2022-04-06T09:59:21Z")

</div>

Exceptions have their shortcomings and APIs are more explicit without them. In Kotlin expressing the success or failure of an operation is easy and elegant with a custom class hierarchy, like [Roman Elizarov suggested](https://elizarov.medium.com/kotlin-and-exceptions-8062f589d07):

```auto
sealed class ParsedDate {
    data class Success(val date: Date) : ParsedDate()
    data class Failure(val errorOffset: Int) : ParsedDate()
}

```

Another option would be the use of [`Result`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-result/) type, which could include the success value or an exception.

But what to do in the case of methods that would usually return `void` and an exception in the case of error? Since the caller is not necessarily interested in the return value it would be easy to forget error handling:

```auto
obj.possiblyFailingOperation(x)

```

Maybe the root cause here is the mixture of two programming styles: imperative programming with side effects and functional style of error handling! If the `obj` in my example wouldn’t be mutated but a “mutated copy” would be returned by `possiblyFailingOperation`, then the caller would still need to do something with the result of the operation.

Here is an example of such a mixture of functional error handling and imperative side-effects:

```auto
fun possiblyFailingOperation(x: Int) Result<Unit> {
  return if (x < 0) {
    Result.failure(IllegalArgumentException()) // could easily be ignored!
  } else {
    Result.success(Unit)
  }
  // perform some side-effect
}

```

Pure imperative approach would look like this:

```auto
fun possiblyFailingOperation(x: Int) Result<Unit> {
  require(x > 0)
  // perform some side-effect
}

```

Pure functional style would like this this (assuming the function is member of `Thing` class):

```auto
fun possiblyFailingOperation(x: Int) : Result<Thing> {
  return if (x < 0) {
    Result.failure(IllegalArgumentException())
  } else {
    Result.success(this.copy(x = x))
  }
}

```

So, does error handling without exceptions make sense with imperative OOP code at all? Wouldn’t it be better to decide for one of the pure approaches?

A mixed approach could be to use result objects only for methods returning a value and exceptions only for mutation methods, but then there would be two approaches for the same thing in a single code base and even in the same class!

In the case of using exception as a return value (and not throwing them) would it make sense to create a new instance in every case with its own (costly) stacktrace or would it be sufficient to have singleton?

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [April 6, 2022, 12:43pm UTC](https://discuss.kotlinlang.org/t/result-objects-instead-of-exceptions/24548/2 "2022-04-06T12:43:13Z")

</div>

I think this is one of reasons why exceptions were invented in the first place. Initially, we often returned “status” from many functions and the caller should verify whether it was success or not. But it turned out people very often miss errors. Exceptions are a more “aggressive” way of signalling errors.

I’m also interested, how people who prefer “either/result” over exceptions handle this problem 🙂

---

<div class="post-metadata">

**Author:** ![medium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/medium/32/10404_2.png) [@medium](https://discuss.kotlinlang.org/u/medium)\
**Post date:** [April 6, 2022, 6:58pm UTC](https://discuss.kotlinlang.org/t/result-objects-instead-of-exceptions/24548/3 "2022-04-06T18:58:55Z")

</div>

Maybe it was not clear enough in my examples, but I think the “trick” to force the caller to handle the result with the `Either`/`Result` approach, is to avoid side-effects. If you don’t have side-effects the operation is only useful if you get the mutated copy.

First let’s have a look at the imperative, exception-based approach:

```auto
class MutableThing(value: Int) {
  value: Int = value
    private set

  fun operate(x: Int) {
    require(x > 0)
    value = value + x
  }
}

```

If a caller would call `operate` he can not forget to handle the error case:

```auto
val thing = MutableThing(1)
thing.operate(-1) // bang!

```

The same with a result object wouldn’t force the caller to handle the in principle uninteresting result:

```auto
class MutableThing(value: Int) {
  value: Int = value
    private set

  fun operate(x: Int) : Result<Unit> {
    if (x <= 0) {
      return Result.failure(IllegalArgumentException())
    } 
    value = value + x
    return Result.success(Unit)
  }
}

```

Since the caller doesn’t _need_ the result, he can easily ignore it:

```auto
val thing = MutableThing(1)
thing.operate(-1) // result ignored, error swallowed!

```

The solution would be to have an immutable class, because then only the result of an operation on such an object would be useful, since the original object would stay the same:

```auto
class ImmutableThing(val value: Int) {
  fun operate(x: Int): Result<ImmutableThing> {
    if (x <= 0) {
      return Result.failure(IllegalArgumentException())
    } 
    val updatedCopy = Result(value + x)
    return Result.success(updatedCopy)
}

```

Now the caller is forced to to something with the result.

```auto
val thing = MutableThing(1)
thing.operate(-1)
  .onSuccess { ... }
  .onFailure { ... }

```

That’s why I’m questioning whether one should decide for a _pure functional_ approach with result objects and immutable objects **or** for a _pure imperative_ approach with mutable objects and exceptions.

---

<div class="post-metadata">

**Author:** ![larcos.1](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/larcos.1/32/8115_2.png) [@larcos.1](https://discuss.kotlinlang.org/u/larcos.1)\
**Post date:** [April 13, 2022, 2:21pm UTC](https://discuss.kotlinlang.org/t/result-objects-instead-of-exceptions/24548/4 "2022-04-13T14:21:30Z")

</div>

I’ve recently changed my style to use immutability with Result instead of throwing exceptions. Throwing exceptions was certainly “easier” because it required less code and less thinking, but I feel the advantages of maintenance and clarity will outweigh the costs.

---

<div class="post-metadata">

**Author:** ![mecoFarid](https://avatars.discourse-cdn.com/v4/letter/m/439d5e/32.png) [@mecoFarid](https://discuss.kotlinlang.org/u/mecoFarid)\
**Post date:** [December 5, 2022, 6:52am UTC](https://discuss.kotlinlang.org/t/result-objects-instead-of-exceptions/24548/5 "2022-12-05T06:52:58Z")

</div>

I would definitely be against doing something like.

```auto
if (x <= 0) {
    return Result.failure(IllegalArgumentException())
}

```

`IllegalArgumentException` and etc. are system failures not a business logic check. So it better be written like and should not be caught/handled.

```auto
require(x <= 0) {"x must never be equal or less than zero "}

```

If your `x <= 0` check is related to business logic then you should have your own custom exception or error type.

---

<div class="post-metadata">

**Author:** ![medium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/medium/32/10404_2.png) [@medium](https://discuss.kotlinlang.org/u/medium)\
**Post date:** [December 5, 2022, 8:33am UTC](https://discuss.kotlinlang.org/t/result-objects-instead-of-exceptions/24548/6 "2022-12-05T08:33:02Z")

</div>

I’d say that the form in which errors are communicated is not limited to certain cases (e.g. business logic or not). Rust, for example, doesn’t have exceptions at all, so another mechanism must be used for _all_ error cases in Rust. But I agree with you, that it is at least uncommon to handle errors in that way in Java and Kotlin.
