In a way it doesn't matter that much. You can use Kotlins nullability system, the Result type, a sealed class or arrows Either. Usually I would runtime exceptions should be for unrecoverable errors in all contexts (just crash the program). All the other options are basically there to give the caller an option to either recover or crash. (Which is good, since some contexts might be able to recover, while others can't). They also add honesty to the function signatures, since they now clearly show they can fail. These are things however that add correctness to code. The more complex your application is, the more correctness you want. On the other hand.. if it's only a simple crud application, it matters less