仅在Java或Kotlin注释异常变量时自动记录catch块

Jac*_* Wu 9 java aop code-generation annotations kotlin

我想为Java或Kotlin做这个:给出下面的代码

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

在构建期间自动在position1添加日志记录语句.我可以使用AspectJ为catch块添加代码(对于Java和Kotlin),但它适用于所有catch块,我无法检查是否存在@AutoLog注释并且只在它出现时才添加代码.所以我想我必须转向Java(或KAPT for Kotlin)的APT(注释处理工具)?

顺便说一句,我在这里找到了一个KAPT代码生成示例:https://github.com/JetBrains/kotlin-examples/tree/master/gradle/kotlin-code-generation ,但它会生成代码来分隔文件,而我想要的是do是修改原始文件/类并在catch块中添加语句.

ape*_*lla 1

您可以使用 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")
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码生成以下输出:

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)
Run Code Online (Sandbox Code Playgroud)

这不是一个完美的解决方案,因为它受到更多限制(例如没有多重捕获)并且语法略有不同,但最终结果是可比较的。