Skip to content

feat: graceful fallback to code default when no default variant resolved#1707

Open
leakonvalinka wants to merge 1 commit intoopen-feature:mainfrom
open-feature-forking:feat/optional-default-variant
Open

feat: graceful fallback to code default when no default variant resolved#1707
leakonvalinka wants to merge 1 commit intoopen-feature:mainfrom
open-feature-forking:feat/optional-default-variant

Conversation

@leakonvalinka
Copy link
Member

@leakonvalinka leakonvalinka commented Mar 4, 2026

This PR

  • when a flag resolves to the default variant, but no default variant exists, the code default value is returned (as opposed to throwing a FlagNotFoundError, which was the behaviour until now)

Related Issues

#1704

Notes

Follow-up Tasks

How to test

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the flag evaluation process by introducing a more robust handling of default values. It ensures that if a flag evaluation results in a default variant but no specific default is configured, the system will now gracefully fall back to the code-provided default value instead of throwing an error. This change improves the resilience and predictability of flag evaluations, preventing unexpected failures in scenarios where flag configurations might be incomplete or misconfigured. Additionally, it includes an upgrade to the gRPC evaluation API to version 2, reflecting updates in the underlying flagd specification.

Highlights

  • Default Variant Resolution: Modified flag resolution logic to return the provided code default value when a flag resolves to the default variant but no explicit default variant is defined in the flag configuration. Previously, this scenario would result in a FlagNotFoundError.
  • gRPC API Version Update: Updated gRPC evaluation service imports and configurations from v1 to v2 across various components, aligning with the latest flagd specification.
  • Resolver Interface and Implementation Updates: Adjusted the Evaluator interface and its implementations (InProcessResolver, RpcResolver, FlagdCore, MockEvaluator) to accept and utilize a defaultValue parameter in all flag resolution methods.
Changelog
  • providers/flagd/spec
    • Updated the subproject commit to reflect the latest flagd specification.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/common/ChannelBuilder.java
    • Added flagd.evaluation.v2.Service to the gRPC service configuration for channel building.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/InProcessResolver.java
    • Modified all resolve*Evaluation methods to pass the defaultValue parameter to the underlying evaluator.
  • providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/RpcResolver.java
    • Updated gRPC evaluation imports from dev.openfeature.flagd.grpc.evaluation to dev.openfeature.flagd.grpc.evaluation.v2.
    • Modified the private resolve method to accept a defaultValue parameter.
    • Adjusted the resolve method logic to return the defaultValue when the evaluation reason is 'DEFAULT' and the variant is empty.
    • Relocated the getBlockingStub method for better code organization.
    • Applied minor formatting adjustments in the observeEventStream method.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdProviderTest.java
    • Updated gRPC evaluation imports to use version 2.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdTestUtils.java
    • Updated gRPC service import to use version 2.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFileTest.java
    • Excluded tests tagged as 'deprecated' from execution.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunInProcessTest.java
    • Excluded tests tagged as 'deprecated' from execution.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunRpcTest.java
    • Excluded tests tagged as 'deprecated' from execution.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/MockEvaluator.java
    • Modified all resolve*Value methods to accept a defaultValue parameter.
    • Updated the private resolve method signature to include defaultValue.
    • Changed the error handling for flags without a default variant to return the defaultValue with a 'DEFAULT' reason, instead of throwing a FlagNotFoundError.
  • providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/RpcResolverTest.java
    • Updated gRPC evaluation imports to use version 2.
  • providers/flagd/test-harness
    • Updated the subproject commit for the test harness.
  • tools/flagd-api/src/main/java/dev/openfeature/contrib/tools/flagd/api/Evaluator.java
    • Modified all resolve*Value methods in the Evaluator interface to include a defaultValue parameter.
  • tools/flagd-core/schemas
    • Updated the subproject commit for flagd core schemas.
  • tools/flagd-core/src/main/java/dev/openfeature/contrib/tools/flagd/core/FlagdCore.java
    • Modified all resolve*Value methods to accept a defaultValue parameter.
    • Updated the private resolve method signature to include defaultValue.
    • Changed the error handling for flags without a default variant to return the defaultValue with a 'DEFAULT' reason, instead of throwing a FlagNotFoundError.
Activity
  • No specific activity (comments, reviews, progress) has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request correctly implements the feature to return the code's default value when a flag resolves to a default variant that doesn't exist, instead of throwing an error. The changes are consistently applied across both RPC and in-process resolvers, including updates to the gRPC v2 API. I've included a couple of suggestions to enhance code readability and follow modern Java best practices.

Comment on lines +60 to +63
new HashMap() {
{
put("service", "flagd.evaluation.v2.Service");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While this follows the existing pattern in the file, using double-brace initialization is generally considered an anti-pattern in modern Java. It creates an anonymous inner class for each instance, which can have performance overhead and may lead to memory leaks if not used carefully. A better alternative is to use java.util.Collections.singletonMap().

                                        java.util.Collections.singletonMap("service", "flagd.evaluation.v2.Service")

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we apply this? if so, i'd apply this to all the other maps too, ofc

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is really better, I would do it

@leakonvalinka leakonvalinka force-pushed the feat/optional-default-variant branch from 8c4ff54 to 23128f6 Compare March 4, 2026 14:36
@leakonvalinka leakonvalinka changed the title feat: return code default when no default variant feat: graceful fallback to code default when no default variant resolved Mar 5, 2026
@leakonvalinka leakonvalinka force-pushed the feat/optional-default-variant branch from 300c0a9 to cf05eaf Compare March 5, 2026 09:04
@leakonvalinka leakonvalinka marked this pull request as ready for review March 5, 2026 09:12
@leakonvalinka leakonvalinka requested a review from a team as a code owner March 5, 2026 09:12
@toddbaert toddbaert force-pushed the feat/optional-default-variant branch 3 times, most recently from 3617e68 to 84eebf6 Compare March 5, 2026 10:10
Signed-off-by: Konvalinka <lea.konvalinka@dynatrace.com>
Signed-off-by: Todd Baert <todd.baert@dynatrace.com>
@toddbaert toddbaert force-pushed the feat/optional-default-variant branch from 84eebf6 to 9c47de0 Compare March 5, 2026 10:14
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

Successfully merging this pull request may close these issues.

6 participants