open-feature / python-sdk-contrib

Community contributions for hooks and reference providers in python
https://openfeature.dev
11 stars 11 forks source link

Flag to prevent exception? #100

Open agardnerIT opened 2 days ago

agardnerIT commented 2 days ago

Is it possible to prevent the thrown Exception and just silently use the default value?

Given the following code, the desired output would be The current colour is: NA but, as you can see, an exception is thrown each time I request the value. By definition this leads to log spam and is somewhat low value given that I do have a default value precisely to protect against this possibility.

flags.json

{
    "$schema": "https://flagd.dev/schema/v0/flags.json",
    "flags": {
      "background-color": {
        "state": "ENABLED",
        "variants": {
          "white": "#D6D4D2",
          "green": "#73A53E",
          "orange": "#FF7C00",
          "lime": "#D3D309",
          "blue": "#4AB9D9"
        },
        "defaultVariant": "green"
     }
    }
}

Code

from openfeature import api
from openfeature.contrib.provider.flagd import FlagdProvider
from openfeature.contrib.provider.flagd.config import ResolverType
import time

api.set_provider(FlagdProvider(
    resolver_type=ResolverType.IN_PROCESS,
    offline_flag_source_path="flags.json",
))

client = api.get_client("my-app")

while True:

    colour = client.get_string_value(flag_key="background-colour", default_value="NA")
    print(f"The current colour is: {colour}")
    time.sleep(1)

Result

Error ErrorCode.FLAG_NOT_FOUND while evaluating flag with key: 'background-colour'
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/openfeature/client.py", line 339, in evaluate_flag_details
    flag_evaluation = self._create_provider_evaluation(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/openfeature/client.py", line 430, in _create_provider_evaluation
    resolution = get_details_callable(*args)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/openfeature/contrib/provider/flagd/provider.py", line 104, in resolve_string_details
    return self.resolver.resolve_string_details(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/openfeature/contrib/provider/flagd/resolvers/in_process.py", line 57, in resolve_string_details
    return self._resolve(key, default_value, evaluation_context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/openfeature/contrib/provider/flagd/resolvers/in_process.py", line 91, in _resolve
    raise FlagNotFoundError(f"Flag with key {key} not present in flag store.")
openfeature.exception.FlagNotFoundError: Flag with key background-colour not present in flag store.
The current colour is: NA

Backwards Compatible Change

Perhaps:

colour = client.get_string_value(flag_key="background-colour", default_value="NA", throw_exception=False)
federicobond commented 2 days ago

Hi @agardnerIT, thanks for reporting this. I'm pretty sure the traceback you see printed is just a log message, and no exception is actually thrown by the SDK, as it would be against the spec. This PR removed the logged message as it was considered too verbose for the evaluation path.

From the OpenFeature spec, Requirement 1.4.10:

Methods, functions, or operations on the client MUST NOT throw exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the default value in the event of abnormal execution. Exceptions include functions or methods for the purposes for configuration or setup.

beeme1mr commented 1 day ago

We recently updated the spec to avoid logging in hot code paths. Instead, a logging hook should be used.

beeme1mr commented 1 day ago

Hey @agardnerIT, are you running the latest version? We reduced the logging in a previous version and I'm having trouble finding where this log message is coming from.

@federicobond @gruebel do either of you see where this log message could be coming from? I've checked both flagd and the SDK.

federicobond commented 1 day ago

I'm pretty sure it's the one already removed by your PR @beeme1mr: https://github.com/open-feature/python-sdk/pull/347

It should not appear in the latest version.