Is there an idiomatic way to create a dynamic Proxy in Kotlin?
I've been trying with
java.reflect.Proxy
with awful results
This proxy job is to intercept, detect if a particular exception is throw and if so unwrap it and throw the underlying exception. This has to work with suspend functions
class UnwrapExceptionProxy<T>(private val instance: T): InvocationHandler {
@Suppress("UNCHECKED_CAST")
override fun invoke(proxy: Any, method: Method, args: Array<out Any?>?): Any? {
val function = method.kotlinFunction!!
return if (function.isSuspend) {
val parameters = Array(args!!.size - 1) {args[it] }
val continuation = args.last() as Continuation<Any?>
method.invoke(instance, *parameters, Continuation<Any?>(continuation.context) { result ->
val wrappedError = result.exceptionOrNull() as? MyWrapException
if (wrappedError == null) {
continuation.resumeWith(result)
} else {
continuation.resumeWith(Result.failure(wrappedError.wrapped))
}
})
} else {
val parameters = args ?: arrayOf()
try {
method.invoke(instance, *parameters)
} catch (e: MyWrapException) {
throw e.wrapped
}
}
}
}
1. First, I'm not sure if I've handled the suspend function correctly
2. I get
java.lang.reflect.UndeclaredThrowableException
every time my kotlin code throws a non
RuntimeException
Is there no way to write a Proxy for kotlin? I cannot force declaring all checked exceptions and I wanted to make this as transparent as possible.