Skip to content

Commit 12b3ca3

Browse files
authoredMar 20, 2025··
fix(tracing): Fix InvalidOperation (#4179)
`InvalidOperation` can occur when using tracing if the `Decimal` class's global context has been modified to set the precision below 6. This change fixes this bug by setting a custom context for our `quantize` call. Fixes #4177
1 parent 5715734 commit 12b3ca3

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed
 

‎sentry_sdk/tracing_utils.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import sys
66
from collections.abc import Mapping
77
from datetime import timedelta
8-
from decimal import ROUND_DOWN, Decimal
8+
from decimal import ROUND_DOWN, Context, Decimal
99
from functools import wraps
1010
from random import Random
1111
from urllib.parse import quote, unquote
@@ -871,7 +871,11 @@ def _generate_sample_rand(
871871
sample_rand = rng.uniform(lower, upper)
872872

873873
# Round down to exactly six decimal-digit precision.
874-
return Decimal(sample_rand).quantize(Decimal("0.000001"), rounding=ROUND_DOWN)
874+
# Setting the context is needed to avoid an InvalidOperation exception
875+
# in case the user has changed the default precision.
876+
return Decimal(sample_rand).quantize(
877+
Decimal("0.000001"), rounding=ROUND_DOWN, context=Context(prec=6)
878+
)
875879

876880

877881
def _sample_rand_range(parent_sampled, sample_rate):

‎tests/tracing/test_sample_rand.py

+26
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import decimal
12
from unittest import mock
23

34
import pytest
@@ -53,3 +54,28 @@ def test_transaction_uses_incoming_sample_rand(
5354
# Transaction event captured if sample_rand < sample_rate, indicating that
5455
# sample_rand is used to make the sampling decision.
5556
assert len(events) == int(sample_rand < sample_rate)
57+
58+
59+
def test_decimal_context(sentry_init, capture_events):
60+
"""
61+
Ensure that having a decimal context with a precision below 6
62+
does not cause an InvalidOperation exception.
63+
"""
64+
sentry_init(traces_sample_rate=1.0)
65+
events = capture_events()
66+
67+
old_prec = decimal.getcontext().prec
68+
decimal.getcontext().prec = 2
69+
70+
try:
71+
with mock.patch(
72+
"sentry_sdk.tracing_utils.Random.uniform", return_value=0.123456789
73+
):
74+
with sentry_sdk.start_transaction() as transaction:
75+
assert (
76+
transaction.get_baggage().sentry_items["sample_rand"] == "0.123456"
77+
)
78+
finally:
79+
decimal.getcontext().prec = old_prec
80+
81+
assert len(events) == 1

0 commit comments

Comments
 (0)
Please sign in to comment.