Вместо использования аннотаций вы можете использовать некоторые функции Kotlin для создания собственных функций, которые работают аналогично стандартному try { ... } catch { ... }
, но также регистрировать исключения.Вот краткий пример:
sealed class Result<S>
class Success<S>(val value: S) : Result<S>()
class Error<S, E : Throwable>(val error: E) : Result<S>()
fun <S> loggingTry(block: () -> S): Result<S> {
return try {
Success(block())
} catch (e: Throwable) {
Error(e)
}
}
inline infix fun <reified E : Throwable, R> Result<out R>.catch(handler: (E) -> R): R {
return when (this) {
is Success -> value
is Error<*, *> -> if (error is E) {
println("Error $error is being handled") // replace this with your own logging
handler(error)
} else throw error
}
}
fun main(args: Array<String>) {
val x = loggingTry {
1 / 0
} catch { e: ArithmeticException ->
3
}
println("Result: $x")
loggingTry {
1 / 0
} catch { e: NullPointerException ->
println("This won't be called, the exception will just be re-thrown")
}
}
Этот код генерирует следующий вывод:
Error java.lang.ArithmeticException: / by zero is being handled
Division result was 3
Exception in thread "main" java.lang.ArithmeticException: / by zero
at MainKt$main$1.invoke(Main.kt:34)
at MainKt$main$1.invoke(Main.kt)
at MainKt.loggingTry(Main.kt:8)
at MainKt.main(Main.kt:33)
Это не идеальное решение, так как оно более ограничено (например, не мульти-улов) иимеет немного другой синтаксис, но конечный результат сопоставим.