Is it possible to rethrow certain exceptions whilst logging and suppressing all others in instrumented code for ByteBuddy?

Viewed 39

I am instrumenting various methods with ByteBuddy's @Advice.OnMethodEnter and @Advice.OnMethodExit and generally do not want any errors/exceptions in the added code to impact on the original code in these methods. However, there are a few specific exceptions that are thrown in the instrumented code that are required for other behaviour and cannot just be suppressed using .withExceptionHandler(Advice.ExceptionHandler.Default.SUPPRESSING) and suppress = Throwable.class.

I am looking for a way to log and suppress most exceptions thrown in the instrumented code whilst allowing/rethrowing a few specified exceptions.

So far I have looking into creating and using a new ExceptionHandler that implements Advice.ExceptionHandler, this is then added using .withExceptionHandler(newExceptionHandler). Pseudocode for this is:

class newExceptionHandler implements Advice.ExceptionHandler {

        @Override
        public StackManipulation resolve(MethodDescription instrumentedMethod, TypeDescription instrumentedType) {

            if (allowedExceptions.contains(currentException)) {
                return Throw.INSTANCE;
            } else {
                // LOG EXCEPTION
                return Removal.SINGLE;
            }
        }
    }

However, I could not find a way to access the type of the thrown exception in resolve and this open issue leads me to believe this may not be possible currently. I have a similar issue of being unable to access the exception when attempting to use MethodInvocation.invoke().

Is there a way to access and use the type of exception in the ByteCode generated by resolve/invoke or any other way to have more customisable exception handling with ByteBuddy and avoid wrapping all the instrumented code with try catch blocks?

Thanks for any help.

1 Answers

For more complex handling, you might rather add explicit try-catch blocks to your advice code. Suppression is rather meant as a fail-safe to avoid leaking your errors into user code.

If you wanted to add a complex error handler to many advice methods, you can also consider advicing your advice code before applying it. You can do this at runtime if you extract the byte code from the dynamic type (advice takes a ClassFileLocator for this. Or you can apply a build plugin.

Related