Propagate non-recoverable JSON conversion failures instead of demoting them to a generic 500 - #6
Draft
apoupard wants to merge 1 commit into
Draft
Propagate non-recoverable JSON conversion failures instead of demoting them to a generic 500#6apoupard wants to merge 1 commit into
apoupard wants to merge 1 commit into
Conversation
…ead of demoting them to a generic 500 spring-cloudGH-1429/ef533f377 already made convertNonMessageInputIfNecessary rethrow (rather than swallow) a JSON conversion failure when the request's Content-Type is JSON (failOnJsonError), fixing a misleading ClassCastException into a real Jackson exception in the logs. But that rethrown exception is still wrapped as a plain IllegalStateException by convertInputPublisherIfNecessary, indistinguishable from any other conversion failure - so it still resolves to a generic 500, and there is no way for a downstream consumer (a web framework's exception resolver, a custom @ControllerAdvice, etc.) to recognize "this was a deliberate, non-recoverable rejection" without inspecting the message/cause chain. Add NonRecoverableConversionException, a narrow MessageConversionException subtype thrown only from the failOnJsonError path, and let it propagate unwrapped through convertInputPublisherIfNecessary. This adds no new dependency (MessageConversionException already lives in spring-messaging, a non-optional dependency of this module) and changes no existing behavior for any other exception type. Known follow-up, intentionally out of scope here: a function declared as Function<Message<T>, R> (explicit Message-wrapped type) never reaches this path at all - convertInputMessageIfNecessary deliberately returns the original, unconverted message whenever the target type is itself Message<T> (to support legitimate no-conversion-needed cases like KafkaNull), which silently masks the same class of failure. Functions declared over the plain payload type (the common case, and the only shape spring-cloud-function's own new PojoFunctionIntegrationTests covers) are unaffected and fixed by this change.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
5 tasks
apoupard
pushed a commit
to komune-io/fixers-f2
that referenced
this pull request
Aug 5, 2026
…une-io/spring-cloud-function#6 is merged Hypothetical/deliberately non-compiling: shows what F2's SimpleFunctionRegistry vendoring would look like if upstream (via #6) already threw and rethrew NonRecoverableConversionException natively. That PR only touches SimpleFunctionRegistry - JsonMessageConverter.java, SmartCompositeMessageConverter.java, and both exception-handler mappings stay exactly as they are, since none of that is in scope for #6. - Deletes F2's own NonRecoverableConversionException.java - would come from the (not-yet-real) upstream spring-cloud-function-context jar instead. - SimpleFunctionRegistry.convertInputPublisherIfNecessary keeps the same catch clauses, but they're no longer KOMUNE-marked: this content would already be present in a fresh extract at the hypothetical merged tag, not something F2 is patching in anymore. The file is still vendored overall, for the unrelated typed List<T> collection deserialization patch elsewhere in it. Does not compile against F2's actual current spring-cloud-function-context dependency, on purpose - there is no real released version with #6 in it. Not mergeable as-is; this commit exists to answer "what does the diff look like if the upstream PR lands," not to ship.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
spring-cloudGH-1429 (ef533f3, already on
main) madeconvertNonMessageInputIfNecessaryrethrow (rather than swallow) a JSON conversion failure when the request'sContent-Typeis JSON (failOnJsonError), fixing a misleadingClassCastExceptioninto a real Jackson exception in the logs. That's a great fix for the log message - but the rethrown exception is still wrapped as a plainIllegalStateExceptionbyconvertInputPublisherIfNecessary, indistinguishable from any other conversion failure. Two consequences:@ControllerAdvice, an app's own error handler) to recognize "this converter deliberately, definitively rejected this input" without inspecting the message/cause chain.This PR adds
NonRecoverableConversionException, a narrowMessageConversionExceptionsubtype thrown only from thefailOnJsonErrorpath, and lets it propagate unwrapped throughconvertInputPublisherIfNecessaryinstead of being folded into the genericIllegalStateExceptionbucket.MessageConversionExceptionalready lives inspring-messaging, a non-optional dependency ofspring-cloud-function-context.failOnJsonErrorbranch's exception type changes.Known follow-up (intentionally out of scope here)
A function declared as
Function<Message<T>, R>(explicitMessage-wrapped type) never reaches this path at all:convertInputMessageIfNecessarydeliberately returns the original, unconverted message whenever the target type is itselfMessage<T>(to support legitimate no-conversion-needed cases likeKafkaNull), which silently masks the same class of failure a different way. Functions declared over the plain payload type - the common case, and the only shape the newPojoFunctionIntegrationTestscovers - are unaffected and fixed by this change.Test plan
SimpleFunctionRegistryTests#testReactivePojoFunctionPropagatesNonRecoverableConversionExceptionForMalformedJson(new) - removal-proofed: fails without the fix, passes with it.SimpleFunctionRegistryTests#testReactiveFunctionMessages(existing, valid-JSON case) - still green, confirming no behavior change on the success path.spring-cloud-function-context+spring-cloud-function-websuite: 199 tests, 0 failures, 0 errors (including the newPojoFunctionIntegrationTests).Was previously opened against spring-cloud#1436 by mistake and closed - this is the fork-local equivalent.