I want to create function which will try to call main function. If it is ok return the resutl of this function outside. But if it is failed - call another function(fallback function) and return its result outside. If both failed - exception of second function should be propagated.
I've creare dollowing function:
fun<T> callWithFallback(
main: () -> T,
fallback: () -> T
): T = try {
main()
} catch (e: Exception) {
logger.warn(e) { "main call failed: ${e.message}" }
if (/*some condition*/) {
try {
fallback()
} catch (e: LDAPException) {
logger.warn(e) { "Repeated call failed: ${e.message}" }
throw e
}
}
throw e
}
in case of main is failed - fallback() is called but even if it is successsful - exception is thrown (last throw e is called)
I tried to add return
fun<T> callWithFallback(
main: () -> T,
fallback: () -> T
): T = try {
main()
} catch (e: Exception) {
logger.warn(e) { "main call failed: ${e.message}" }
if (/*some condition*/) {
try {
return fallback()
} catch (e: LDAPException) {
logger.warn(e) { "Repeated call failed: ${e.message}" }
throw e
}
}
throw e
}
But it leads to compile error.
How can I fix it ?
The problem of your current implementation comes from the
ifstatement withoutelsein your firstcatchclause :To know what to return from the catch, Kotlin compiler looks at the last statement it contains. Here, it is
throw e, not the if that contains the wanted fallback.As your
ifhas noelsebranch, it is considered a statement instead of an expression. Therefore, it cannot return anything. You can test this assertion by removingthrow efrom thecatchclause. The compiler will then issue a warning to explain it cannot return anything from thecatchclause:To fix your problem, you can move the
throw estatement at the bottom of your function in an else clause, like so:Doing so makes the
if/elsethe latest statement in thecatchclause, and as it is an expression (due to the presence of the else branch), its result is considered the return value of the catch.