|
6 | 6 | from sentry_sdk.integrations.boto3._context import AwsCallContext |
7 | 7 | from sentry_sdk.integrations.boto3._instrumentation import ( |
8 | 8 | _finish_active_http_child_span, |
9 | | - _finish_client_span, |
| 9 | + _instrument_streaming_body, |
10 | 10 | _sentry_before_sign, |
11 | 11 | _sentry_request_created, |
12 | 12 | _start_client_span, |
13 | 13 | ) |
14 | | -from sentry_sdk.utils import capture_internal_exceptions |
| 14 | +from sentry_sdk.utils import capture_internal_exceptions, nullcontext |
15 | 15 |
|
16 | 16 | if TYPE_CHECKING: |
17 | 17 | from typing import Any, Optional, Union |
@@ -58,22 +58,21 @@ def sentry_patched_make_api_call( |
58 | 58 |
|
59 | 59 | with capture_internal_exceptions(): |
60 | 60 | span = _start_client_span(ctx) |
61 | | - if span is not None: |
62 | | - span.__enter__() |
63 | 61 |
|
64 | | - try: |
65 | | - parsed = orig_make_api_call(self, operation_name, api_params) |
66 | | - except BaseException as exc: |
67 | | - if span is not None: |
68 | | - with capture_internal_exceptions(): |
69 | | - _finish_active_http_child_span(span) |
70 | | - span.__exit__(type(exc), exc, exc.__traceback__) |
71 | | - raise |
| 62 | + span_ctx = span or nullcontext() |
| 63 | + with span_ctx as span: |
| 64 | + try: |
| 65 | + parsed = orig_make_api_call(self, operation_name, api_params) |
| 66 | + finally: |
| 67 | + # stdlib HTTP span must leave stack before boto3 parent ctx |
| 68 | + # manager restores the previous span. |
| 69 | + if span is not None: |
| 70 | + with capture_internal_exceptions(): |
| 71 | + _finish_active_http_child_span(span) |
72 | 72 |
|
73 | 73 | if span is not None: |
74 | 74 | with capture_internal_exceptions(): |
75 | | - _finish_active_http_child_span(span) |
76 | | - _finish_client_span(span, parsed) |
| 75 | + _instrument_streaming_body(span, parsed) |
77 | 76 | return parsed |
78 | 77 |
|
79 | 78 | BaseClient.__init__ = sentry_patched_init # type: ignore |
|
0 commit comments