Автоматическое ведение журнала в блоке перехвата, только когда аннотируется переменная исключения, для Java или Kotlin - PullRequest
0 голосов
/ 08 октября 2018

Я хочу сделать это для Java или Kotlin: с учетом приведенного ниже кода

try {...
} catch ( @ AutoLog e: Exception) {// position1
}

добавление оператора регистрации в position1 автоматически во время сборки.Я могу добавить код с AspectJ для блока catch (как для Java, так и для Kotlin), но это для всех блоков catch, я не могу проверить, присутствует ли аннотация @AutoLog, и добавлять код только тогда, когда он есть.Поэтому я думаю, что мне нужно обратиться к APT (инструмент обработки аннотаций) для Java (или KAPT для Kotlin)?

Кстати, я нашел здесь пример генерации кода KAPT: ​​https://github.com/JetBrains/kotlin-examples/tree/master/gradle/kotlin-code-generation, но он генерируеткод для отдельного файла, в то время как я хочу изменить исходный файл / класс и добавить оператор в блоке catch.

1 Ответ

0 голосов
/ 30 октября 2018

Вместо использования аннотаций вы можете использовать некоторые функции 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)

Это не идеальное решение, так как оно более ограничено (например, не мульти-улов) иимеет немного другой синтаксис, но конечный результат сопоставим.

...