Skip to content

Commit 37650c2

Browse files
authored
Merge branch 'master' into toxgen/update
2 parents 431ccab + b12823e commit 37650c2

File tree

7 files changed

+100
-3
lines changed

7 files changed

+100
-3
lines changed

sentry_sdk/integrations/aws_lambda.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs):
138138
timeout_thread = TimeoutThread(
139139
waiting_time,
140140
configured_time / MILLIS_TO_SECONDS,
141+
isolation_scope=scope,
142+
current_scope=sentry_sdk.get_current_scope(),
141143
)
142144

143145
# Starting the thread to raise timeout warning exception

sentry_sdk/integrations/gcp.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,12 @@ def sentry_func(functionhandler, gcp_event, *args, **kwargs):
7575
):
7676
waiting_time = configured_time - TIMEOUT_WARNING_BUFFER
7777

78-
timeout_thread = TimeoutThread(waiting_time, configured_time)
78+
timeout_thread = TimeoutThread(
79+
waiting_time,
80+
configured_time,
81+
isolation_scope=scope,
82+
current_scope=sentry_sdk.get_current_scope(),
83+
)
7984

8085
# Starting the thread to raise timeout warning exception
8186
timeout_thread.start()

sentry_sdk/utils.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,17 +1484,37 @@ class TimeoutThread(threading.Thread):
14841484
waiting_time and raises a custom ServerlessTimeout exception.
14851485
"""
14861486

1487-
def __init__(self, waiting_time, configured_timeout):
1488-
# type: (float, int) -> None
1487+
def __init__(
1488+
self, waiting_time, configured_timeout, isolation_scope=None, current_scope=None
1489+
):
1490+
# type: (float, int, Optional[sentry_sdk.Scope], Optional[sentry_sdk.Scope]) -> None
14891491
threading.Thread.__init__(self)
14901492
self.waiting_time = waiting_time
14911493
self.configured_timeout = configured_timeout
1494+
1495+
self.isolation_scope = isolation_scope
1496+
self.current_scope = current_scope
1497+
14921498
self._stop_event = threading.Event()
14931499

14941500
def stop(self):
14951501
# type: () -> None
14961502
self._stop_event.set()
14971503

1504+
def _capture_exception(self):
1505+
# type: () -> ExcInfo
1506+
exc_info = sys.exc_info()
1507+
1508+
client = sentry_sdk.get_client()
1509+
event, hint = event_from_exception(
1510+
exc_info,
1511+
client_options=client.options,
1512+
mechanism={"type": "threading", "handled": False},
1513+
)
1514+
sentry_sdk.capture_event(event, hint=hint)
1515+
1516+
return exc_info
1517+
14981518
def run(self):
14991519
# type: () -> None
15001520

@@ -1510,6 +1530,18 @@ def run(self):
15101530
integer_configured_timeout = integer_configured_timeout + 1
15111531

15121532
# Raising Exception after timeout duration is reached
1533+
if self.isolation_scope is not None and self.current_scope is not None:
1534+
with sentry_sdk.scope.use_isolation_scope(self.isolation_scope):
1535+
with sentry_sdk.scope.use_scope(self.current_scope):
1536+
try:
1537+
raise ServerlessTimeoutWarning(
1538+
"WARNING : Function is expected to get timed out. Configured timeout duration = {} seconds.".format(
1539+
integer_configured_timeout
1540+
)
1541+
)
1542+
except Exception:
1543+
reraise(*self._capture_exception())
1544+
15131545
raise ServerlessTimeoutWarning(
15141546
"WARNING : Function is expected to get timed out. Configured timeout duration = {} seconds.".format(
15151547
integer_configured_timeout
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Need to add some ignore rules in this directory, because the unit tests will add the Sentry SDK and its dependencies
2+
# into this directory to create a Lambda function package that contains everything needed to instrument a Lambda function using Sentry.
3+
4+
# Ignore everything
5+
*
6+
7+
# But not index.py
8+
!index.py
9+
10+
# And not .gitignore itself
11+
!.gitignore
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import os
2+
import time
3+
4+
import sentry_sdk
5+
from sentry_sdk.integrations.aws_lambda import AwsLambdaIntegration
6+
7+
sentry_sdk.init(
8+
dsn=os.environ.get("SENTRY_DSN"),
9+
traces_sample_rate=1.0,
10+
integrations=[AwsLambdaIntegration(timeout_warning=True)],
11+
)
12+
13+
14+
def handler(event, context):
15+
sentry_sdk.set_tag("custom_tag", "custom_value")
16+
time.sleep(15)
17+
return {
18+
"event": event,
19+
}

tests/integrations/aws_lambda/test_aws_lambda.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,31 @@ def test_timeout_error(lambda_client, test_environment):
223223
assert exception["mechanism"]["type"] == "threading"
224224

225225

226+
def test_timeout_error_scope_modified(lambda_client, test_environment):
227+
lambda_client.invoke(
228+
FunctionName="TimeoutErrorScopeModified",
229+
Payload=json.dumps({}),
230+
)
231+
envelopes = test_environment["server"].envelopes
232+
233+
(error_event,) = envelopes
234+
235+
assert error_event["level"] == "error"
236+
assert (
237+
error_event["extra"]["lambda"]["function_name"] == "TimeoutErrorScopeModified"
238+
)
239+
240+
(exception,) = error_event["exception"]["values"]
241+
assert not exception["mechanism"]["handled"]
242+
assert exception["type"] == "ServerlessTimeoutWarning"
243+
assert exception["value"].startswith(
244+
"WARNING : Function is expected to get timed out. Configured timeout duration ="
245+
)
246+
assert exception["mechanism"]["type"] == "threading"
247+
248+
assert error_event["tags"]["custom_tag"] == "custom_value"
249+
250+
226251
@pytest.mark.parametrize(
227252
"aws_event, has_request_data, batch_size",
228253
[

tests/integrations/gcp/test_gcp.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ def test_timeout_error(run_cloud_function):
196196
functionhandler = None
197197
event = {}
198198
def cloud_function(functionhandler, event):
199+
sentry_sdk.set_tag("cloud_function", "true")
199200
time.sleep(10)
200201
return "3"
201202
"""
@@ -219,6 +220,8 @@ def cloud_function(functionhandler, event):
219220
assert exception["mechanism"]["type"] == "threading"
220221
assert not exception["mechanism"]["handled"]
221222

223+
assert envelope_items[0]["tags"]["cloud_function"] == "true"
224+
222225

223226
def test_performance_no_error(run_cloud_function):
224227
envelope_items, _ = run_cloud_function(

0 commit comments

Comments
 (0)