Which one is better? 1. ```class SomeThing { ...
# getting-started
j
Which one is better? 1.
Copy code
class SomeThing {
    fun throwAnException(): Nothing { ... }
}

// ...
val s: SomeThing = ...
if (...) 
    s.throwAnException()
2.
Copy code
class SomeThing {
    fun anException(): Exception { ... }
}

// ...
val s: SomeThing = ...
if (...) 
    throw s.anException()
s
Trick question, the answer is actually
Copy code
val s: SomeThing = ...
if (...) 
    return s.someFailureResult()
😁
☝️ 4
☝🏽 1
But in seriousness I don't think the choice between your options 1 and 2 makes a whole lot of difference. Maybe an argument could be made for preferring 1 because it avoids the possibility of accidentally creating the exception without throwing it.
s
the thing that I don't like in 1. and 2. is that
SomeThing
builds the exception, but doesn't contain the logic that triggers throwing it 🤔 And if
SomeThing
is some kind of exception builder, why instanciate it before it's clear that an exception will be thrown. So that's why I assume
SomeThing
only contains some data, you want to add to the exception message. So maybe 3.
Copy code
// data classes come with a useful toString()-method
data class SomeData(...)

// ...
val d: SomeData = ...

// or check(condition){"generate msg given data: $d"}
require(...) {"something went wrong given data: $d"}
c
The stdlib uses precondition functions
check()
,
checkNotNull()
,
error()
, etc. which follow the semantics of your #1 example. Given that it returns
Nothing
, the compiler is smart enough to give you smart casting, control flow analysis, etc. in response to calling
s.throwAnException()
. You won’t get that with #2, and it leaves you vulnerable to someone calling
s.anException()
but not actually throwing it
e
I think both are useful, and you'll see that in stdlib as well:
kotlin.Result.getOrThrow()
, `.exceptionOrNull()`;
kotlinx.coroutines.Deferred.getCompleted()
,
.getCompletionExceptionOrNull()
n
when in doubt, I would go with the 2nd approach because esp. Java compilers are not smart enough to understand that
throwAnException()
never returns