Skip to content

Commit 8706459

Browse files
committed
feat: optionally disable exceptions on evaluation errors
Signed-off-by: Danju Visvanathan <danju.visvanathan@gmail.com>
1 parent 4af8e95 commit 8706459

2 files changed

Lines changed: 35 additions & 5 deletions

File tree

hooks/openfeature-hooks-opentelemetry/src/openfeature/contrib/hook/opentelemetry/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from openfeature.exception import ErrorCode
44
from openfeature.flag_evaluation import FlagEvaluationDetails, Reason
55
from openfeature.hook import Hook, HookContext, HookHints
6-
from opentelemetry import metrics, trace
6+
from opentelemetry import trace
77
from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE
88

99
OTEL_EVENT_NAME = "feature_flag.evaluation"
@@ -21,6 +21,9 @@ class EventAttributes:
2121

2222

2323
class TracingHook(Hook):
24+
def __init__(self, exclude_exceptions: bool = False):
25+
self.exclude_exceptions = exclude_exceptions
26+
2427
def finally_after(
2528
self,
2629
hook_context: HookContext,
@@ -60,6 +63,8 @@ def finally_after(
6063
def error(
6164
self, hook_context: HookContext, exception: Exception, hints: HookHints
6265
) -> None:
66+
if self.exclude_exceptions:
67+
return
6368
attributes = {
6469
EventAttributes.KEY: hook_context.flag_key,
6570
EventAttributes.RESULT_VALUE: json.dumps(hook_context.default_value),

hooks/openfeature-hooks-opentelemetry/tests/test_otel.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
from openfeature.provider.metadata import Metadata
1313

1414

15+
16+
1517
@pytest.fixture
1618
def mock_get_current_span(monkeypatch):
1719
monkeypatch.setattr(trace, "get_current_span", Mock())
1820

1921

20-
def test_after(mock_get_current_span):
22+
def test_finally_after(mock_get_current_span):
2123
# Given
2224
hook = TracingHook()
2325
hook_context = HookContext(
@@ -40,7 +42,7 @@ def test_after(mock_get_current_span):
4042
trace.get_current_span.return_value = mock_span
4143

4244
# When
43-
hook.after(hook_context, details, hints={})
45+
hook.finally_after(hook_context, details, hints={})
4446

4547
# Then
4648
mock_span.add_event.assert_called_once_with(
@@ -79,7 +81,7 @@ def test_after_evaluation_error(mock_get_current_span):
7981
trace.get_current_span.return_value = mock_span
8082

8183
# When
82-
hook.after(hook_context, details, hints={})
84+
hook.finally_after(hook_context, details, hints={})
8385

8486
# Then
8587
mock_span.add_event.assert_called_once_with(
@@ -104,6 +106,10 @@ def test_error(mock_get_current_span):
104106
evaluation_context=EvaluationContext(),
105107
)
106108
exception = Exception()
109+
attributes = {
110+
"feature_flag.key": "flag_key",
111+
"feature_flag.result.value": "false",
112+
}
107113

108114
mock_span = Mock(spec=Span)
109115
trace.get_current_span.return_value = mock_span
@@ -112,4 +118,23 @@ def test_error(mock_get_current_span):
112118
hook.error(hook_context, exception, hints={})
113119

114120
# Then
115-
mock_span.record_exception.assert_called_once_with(exception)
121+
mock_span.record_exception.assert_called_once_with(exception, attributes)
122+
123+
def test_error_exclude_exceptions(mock_get_current_span):
124+
# Given
125+
hook = TracingHook(exclude_exceptions=True)
126+
hook_context = HookContext(
127+
flag_key="flag_key",
128+
flag_type=FlagType.BOOLEAN,
129+
default_value=False,
130+
evaluation_context=EvaluationContext(),
131+
)
132+
exception = Exception()
133+
134+
mock_span = Mock(spec=Span)
135+
trace.get_current_span.return_value = mock_span
136+
137+
# When
138+
hook.error(hook_context, exception, hints={})
139+
140+
mock_span.record_exception.assert_not_called()

0 commit comments

Comments
 (0)