Fix name resolver bridge listener handling #12441
Open
+55
−2
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.
Fixes #12444
This PR addresses a bug in the
NameResolver.ListenertoNameResolver.Listener2bridge affecting custom NameResolver implementations using Listener.The bridge in
NameResolver.start(Listener)at https://github.com/grpc/grpc-java/blob/master/api/src/main/java/io/grpc/NameResolver.java#L100 unconditionally callsgetValue()on theStatusOr, throwingjava.lang.IllegalStateException: No value present.when the result contains an error.This was identified when upgrading from gRPC
v1.63.3tov1.75.0.The bug occurs due to
DnsNameResolver's error handling changes between versions:v1.63.3: Errors reported viaListener.onError()(https://github.com/grpc/grpc-java/blob/v1.63.x/core/src/main/java/io/grpc/internal/DnsNameResolver.java#L319)v1.75.0: Errors passed viaListener2.onResult2()with a ResolutionResult containing either addresses OR an error (https://github.com/grpc/grpc-java/blob/master/core/src/main/java/io/grpc/internal/DnsNameResolver.java#L322)This PR updates the bridge to check whether
ResolutionResultcontains addresses or an error. It passes the error viaonErrorand addresses viaonAddresses.Reproducing the Issue
The
startOnOldListener_resolverReportsErrortest reproduces a similar issue. It creates a customNameResolverthat reports errors through theResolutionResultlike theDNSNameResolverinv1.75.0, passes an old Listener toresolver.start, which triggers the bridge code path.Without the fix, the bridge calls
getValue()on the error containingStatusOr, throwingIllegalStateException: No value present.With the fix, the bridge checks
hasValue()first and correctly routes tolistener.onError()when appropriate. This ensures backward compatibility forListenerimplementations when resolvers report errors viaResolutionResult.