Skip to content

Commit a0ae9da

Browse files
committed
fix: propagate access denied errors
1 parent 1b202be commit a0ae9da

File tree

4 files changed

+27
-6
lines changed

4 files changed

+27
-6
lines changed

Diff for: aws_lambda_powertools/utilities/feature_flags/appconfig.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
import traceback
23
from typing import Any, Dict, Optional, cast
34

45
from botocore.config import Config
@@ -7,7 +8,7 @@
78

89
from ...shared import jmespath_utils
910
from .base import StoreProvider
10-
from .exceptions import ConfigurationStoreError
11+
from .exceptions import ConfigurationStoreError, StoreClientError
1112

1213
logger = logging.getLogger(__name__)
1314

@@ -85,4 +86,7 @@ def get_configuration(self) -> Dict[str, Any]:
8586

8687
return config
8788
except (GetParameterError, TransformParameterError) as exc:
89+
err_msg = traceback.format_exc()
90+
if "AccessDenied" in err_msg:
91+
raise StoreClientError(err_msg) from exc
8892
raise ConfigurationStoreError("Unable to get AWS AppConfig configuration file") from exc

Diff for: aws_lambda_powertools/utilities/feature_flags/exceptions.py

+7
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,10 @@ class ConfigurationStoreError(Exception):
44

55
class SchemaValidationError(Exception):
66
"""When feature flag schema fails validation"""
7+
8+
9+
class StoreClientError(Exception):
10+
"""When a store raises an exception that should be propagated to the client to fix
11+
12+
For example, Access Denied errors when the client doesn't permissions to fetch config
13+
"""

Diff for: aws_lambda_powertools/utilities/feature_flags/feature_flags.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,7 @@ def get_configuration(self) -> Union[Dict[str, Dict], Dict]:
140140
"""
141141
# parse result conf as JSON, keep in cache for max age defined in store
142142
logger.debug(f"Fetching schema from registered store, store={self._store}")
143-
try:
144-
config = self._store.get_configuration()
145-
except Exception as err:
146-
raise ConfigurationStoreError("Unable to fetch schema from registered store") from err
147-
143+
config = self._store.get_configuration()
148144
validator = schema.SchemaValidator(schema=config)
149145
validator.validate()
150146

Diff for: tests/functional/feature_flags/test_feature_flags.py

+14
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from aws_lambda_powertools.utilities.feature_flags import ConfigurationStoreError, schema
77
from aws_lambda_powertools.utilities.feature_flags.appconfig import AppConfigStore
8+
from aws_lambda_powertools.utilities.feature_flags.exceptions import StoreClientError
89
from aws_lambda_powertools.utilities.feature_flags.feature_flags import FeatureFlags
910
from aws_lambda_powertools.utilities.feature_flags.schema import RuleAction
1011
from aws_lambda_powertools.utilities.parameters import GetParameterError
@@ -487,3 +488,16 @@ def test_match_condition_with_dict_value(mocker, config):
487488
ctx = {"tenant": {"tenant_id": "6", "username": "lessa"}}
488489
toggle = feature_flags.evaluate(name="my_feature", context=ctx, default=False)
489490
assert toggle == expected_value
491+
492+
493+
def test_get_feature_toggle_propagates_access_denied_error(mocker, config):
494+
# GIVEN a schema fetch that raises a StoreClientError
495+
# due to client invalid permissions to fetch from the store
496+
err = "An error occurred (AccessDeniedException) when calling the GetConfiguration operation"
497+
schema_fetcher = init_fetcher_side_effect(mocker, config, GetParameterError(err))
498+
feature_flags = FeatureFlags(schema_fetcher)
499+
500+
# WHEN calling evaluate
501+
# THEN raise StoreClientError error
502+
with pytest.raises(StoreClientError, match="AccessDeniedException") as err:
503+
feature_flags.evaluate(name="Foo", default=False)

0 commit comments

Comments
 (0)