-
Notifications
You must be signed in to change notification settings - Fork 292
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
PubSubInboundChannelAdapter swallows assertion errors #1103
Comments
@artembilan What is the general Spring Integration philosophy when handling @damienhollis I am not sure built-in Java assertions are helpful here -- if a message is malformed, you'd more commonly send it to a dead-letter queue, or do manual logging of some sort. Pub/Sub will redeliver any message that has failed to get acked, so whether auto-ack mode is on or not, you'll still get redelivery, unless the server-side DLQ is enabled. I would suggest doing custom validation logic rather than relying on Assert behavior. |
@damienhollis Also take a look at Spring |
It's not The
So, if you downstream flow throws a Just for info: https://stackoverflow.com/questions/2758224/what-does-the-java-assert-keyword-do-and-when-should-it-be-used |
@elefeint and @artembilan thanks for your responses. The fix for the particular case we encountered was to change the assert to a RuntimeException. So we have already implemented your proposed fix in our code. However, my bigger concern is hitting other assertions in the code and that those will be silently ignored. To us, this seems like a very strange position to take for both spring-integration and for this particular adapter - it does not seem like a sensible default position. Similarly, if we were getting an OutOfMemoryError, I would not want that to just be ignored as it is critical information. For better or worse, we use assert a lot in our code base (maybe something we need to reconsider), so this is worrying. In this particular case we can wrap our call to the service that might throw an AssertionError and convert it to a RuntimeException but that means wherever something is called by spring-integration we need to add this extra logic. |
The Java |
Yes, that was my thought, too. Spring Integration only catches those |
The
and then nothing else happens with them. The last pubsub code to deal with them is in
|
I agree with this assessment. If assertions don't get reported or logged anywhere (i.e. they are swallowed by the framework and it's components) does that mean there is an expectation that applications run with asserts turned off or that all relevant asserts be converted to RuntimeExceptions? It feels like if that is the case, that there should be a warning in the documentation about this. Perhaps in https://docs.spring.io/spring-integration/reference/html/error-handling.html? |
The mismatch is philosophical: Spring Integration expects to handle runtime exceptions, but allow the rest to kill the app (as is proper). Pub/Sub client library, however, must make sure message handling gets completed, no matter what. So the client library catches all Throwables, nacks them and moves on, preventing application shutdown. We can probably catch-log-rethrow non-RuntimeException throwables in Spring Cloud GCP to make this more user-friendly. As a matter of user application practice, it's definitely not ideal to be throwing |
We have treated asserts as checking preconditions but not necessarily as fatal to the whole application, so we have used them a lot. However, thinking more about it and the fact they are subclasses of Error, it makes sense to treat them as fatal in general. I think we will start to replace them with some kind of runtime exception but we can't do the overnight and if other types of errors occur, e.g. OOM it would be useful to log the issue, so we know these things are happening. I think all you really need to do is when you nack the message, you can also log the |
I dug into this behavior again, and while we can work around it in the Spring Integration adapter, the same issue exists in the template level and the underlying client library. You should definitely not keep java Error-throwing assertions in the production code, but at the same time, you are correct in that the Spring Cloud GCP / client library layers should at some point log useful information about an |
Thanks @elefeint - appreciate your work on this and logging At the same time, we are actively working to remove asserts from our code base based on your suggestions and other reading we have done. |
Thanks! I'll close this issue for now; there will likely be nothing to do in Spring Cloud GCP once the underlying client library logging is added. |
Describe the bug
When a message is received via PubSubInboundChannelAdapter and during the message flow it causes an assertion error, there is absolutely no logging. If the adapter is configured to auto acknowledge, the message is simply redelivered over and over. This makes errors caused by assertions very hard to find.
All types of exception should be logged by the PubSubInboundChannelAdapter in some form.
Attached is an example program that demonstrates the issue. To run it do the following:
pubsub.zip
The text was updated successfully, but these errors were encountered: