Skip to content

GrpcExceptionHandler does not seem to be called when using Reactor generated stubs #143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
svametcalf opened this issue Mar 20, 2025 · 6 comments

Comments

@svametcalf
Copy link
Contributor

Greetings!

First of all, very glad to see that gRPC is becoming supported by the Spring ecosystem.

I spent the day attempting to migrate to use this library and found that the GrpcExceptiionHandler was not working as I would have expected it to.

I have created a fork of this project and modified the grpc-reactor sample to demonstrate exactly what is going on here: https://github.com/svametcalf/spring-grpc/tree/reactor-error-handler. In short, I have registered the following exception handler:

@Bean
    GrpcExceptionHandler grpcExceptionHandler() {
        log.info("GrpcExceptionHandler");
        return ex -> {
            if(ex instanceof IllegalArgumentException ){
                log.error("Error in grpc exception", ex);
                return Status.INVALID_ARGUMENT.withDescription(ex.getMessage());
            }
            return Status.INTERNAL.withCause(ex).withDescription(ex.getMessage());
        };
    }

I am getting the following responses when using grpcurl:

❯ grpcurl -d '{"name":"error"}' -plaintext localhost:9090 Simple.SayHello
ERROR:
  Code: Unknown
  Message: 

and

❯ grpcurl -d '{"name":"internal"}' -plaintext localhost:9090 Simple.SayHello
ERROR:
  Code: Unknown
  Message: 

Shouldn't those error codes be INVALID and INTERNAL respectively?

@dsyer
Copy link
Collaborator

dsyer commented Mar 24, 2025

That's sort of interesting. The Salesforce-generated code swallows the exception (and closes the server call), instead of rethrowing. I don't see any options to change that. Maybe you should take it up with the reactive-grpc authors? You can follow an (old) thread here: salesforce/reactive-grpc#234. That issue is still open, and they merged a PR that added the onErrorMap() method to the base BindableService implementation, so you can work around the problem by handling the errors locally in your service. Doesn't seem like a great solution to me.

@dsyer dsyer added the wontfix This will not be worked on label Mar 24, 2025
@dsyer dsyer closed this as completed in fce479b Mar 25, 2025
@dsyer dsyer removed the wontfix This will not be worked on label Mar 25, 2025
@dsyer
Copy link
Collaborator

dsyer commented Mar 25, 2025

This should be working now (and I added a test), but not in AOT (until spring-projects/spring-framework#34642 is fixed).

@svametcalf
Copy link
Contributor Author

Thanks for the quick turnaround!

@svametcalf
Copy link
Contributor Author

Is this what you mean when you mean that the AOT needs to be fixed?

Exception in thread "main" org.springframework.test.context.aot.TestContextAotException: Failed to generate AOT artifacts for test classes [org.springframework.grpc.sample.GrpcServerApplicationTests]
	at org.springframework.test.context.aot.TestContextAotGenerator.lambda$processAheadOfTime$5(TestContextAotGenerator.java:286)
	at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
	at org.springframework.util.MultiValueMapAdapter.forEach(MultiValueMapAdapter.java:179)
	at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:244)
	at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:205)
	at org.springframework.test.context.aot.TestAotProcessor.performAotProcessing(TestAotProcessor.java:91)
	at org.springframework.test.context.aot.TestAotProcessor.doProcess(TestAotProcessor.java:72)
	at org.springframework.test.context.aot.TestAotProcessor.doProcess(TestAotProcessor.java:39)
	at org.springframework.context.aot.AbstractAotProcessor.process(AbstractAotProcessor.java:82)
	at org.springframework.boot.test.context.SpringBootTestAotProcessor.main(SpringBootTestAotProcessor.java:63)
Caused by: org.springframework.test.context.aot.TestContextAotException: Failed to process test class [org.springframework.grpc.sample.GrpcServerApplicationTests] for AOT
	at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:323)
Caused by: org.springframework.test.context.aot.TestContextAotException: Failed to process test class [org.springframework.grpc.sample.GrpcServerApplicationTests] for AOT

	at org.springframework.test.context.aot.TestContextAotGenerator.lambda$processAheadOfTime$5(TestContextAotGenerator.java:277)
	... 9 more
Caused by: org.springframework.beans.factory.aot.AotBeanProcessingException: Error processing bean with name 'org.springframework.grpc.autoconfigure.client.ClientScanConfiguration.default': instance supplier is not supported
Caused by: org.springframework.beans.factory.aot.AotBeanProcessingException: Error processing bean with name 'org.springframework.grpc.autoconfigure.client.ClientScanConfiguration.default': instance supplier is not supported

	at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.getTarget(DefaultBeanRegistrationCodeFragments.java:81)
	at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:85)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution$BeanDefinitionsRegistrationGenerator.generateBeanRegistration(BeanRegistrationsAotContribution.java:226)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution$BeanDefinitionsRegistrationGenerator.lambda$generateRegisterBeanDefinitionMethods$2(BeanRegistrationsAotContribution.java:209)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution$BeanDefinitionsRegistrationGenerator.generateRegisterBeanDefinitionMethods(BeanRegistrationsAotContribution.java:207)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution$BeanDefinitionsRegistrationGenerator.lambda$generateRegisterBeanDefinitionsMethod$0(BeanRegistrationsAotContribution.java:171)
	at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:54)
	at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:112)
	at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:89)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution$BeanDefinitionsRegistrationGenerator.generateRegisterBeanDefinitionsMethod(BeanRegistrationsAotContribution.java:166)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.applyTo(BeanRegistrationsAotContribution.java:77)
	at org.springframework.context.aot.BeanFactoryInitializationAotContributions.applyTo(BeanFactoryInitializationAotContributions.java:96)
	at org.springframework.context.aot.ApplicationContextAotGenerator.lambda$processAheadOfTime$0(ApplicationContextAotGenerator.java:58)
	at org.springframework.context.aot.ApplicationContextAotGenerator.withCglibClassHandler(ApplicationContextAotGenerator.java:67)
	at org.springframework.context.aot.ApplicationContextAotGenerator.processAheadOfTime(ApplicationContextAotGenerator.java:53)
	at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:319)
	... 10 more

Execution failed for task ':grpc-reactive:processTestAot'.
> Process 'command '/home/schuyler/.gradle/jdks/eclipse_adoptium-17-amd64-linux.2/bin/java'' finished with non-zero exit value 1

I am trying to run the tests on my fork using Gradle

@dsyer
Copy link
Collaborator

dsyer commented Mar 27, 2025

No, that's unrelated. Gradle is configured to compile AOT tests by default. Don't ask me why. Ask the Spring Boot team (I think it's a "feature" of the Boot Gradle plugin). Mind you, it shouldn't fail that way on that sample, so can you open a new issue here please?

@svametcalf
Copy link
Contributor Author

I am getting a new error after pulling main, and have logged the error here: #147

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants