Skip to content
This repository was archived by the owner on Jun 13, 2023. It is now read-only.

Commit 9923a9d

Browse files
authored
feat(fastapi): adding support for exception handlers (#335)
1 parent 84f710a commit 9923a9d

File tree

6 files changed

+440
-92
lines changed

6 files changed

+440
-92
lines changed

epsagon/modules/fastapi.py

+32-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
from __future__ import absolute_import
66
import wrapt
77
from fastapi.routing import APIRoute
8-
from ..wrappers.fastapi import TracingAPIRoute
8+
from ..wrappers.fastapi import (
9+
TracingAPIRoute,
10+
exception_handler_wrapper,
11+
server_call_wrapper,
12+
)
913
from ..utils import is_lambda_env, print_debug
1014

1115
def _wrapper(wrapped, _instance, args, kwargs):
@@ -30,6 +34,23 @@ def _wrapper(wrapped, _instance, args, kwargs):
3034
kwargs['route_class'] = TracingAPIRoute
3135
return wrapped(*args, **kwargs)
3236

37+
def _exception_handler_wrapper(wrapped, _instance, args, kwargs):
38+
"""
39+
Wraps the handler given to add_exception_handler.
40+
:param wrapped: wrapt's wrapped
41+
:param instance: wrapt's instance
42+
:param args: wrapt's args
43+
:param kwargs: wrapt's kwargs
44+
"""
45+
# Skip on Lambda environment since it's not relevant and might be duplicate
46+
if is_lambda_env():
47+
return wrapped(*args, **kwargs)
48+
49+
if args and len(args) == 2:
50+
args = list(args)
51+
args[1] = exception_handler_wrapper(args[1])
52+
return wrapped(*args, **kwargs)
53+
3354

3455
def patch():
3556
"""
@@ -41,3 +62,13 @@ def patch():
4162
'APIRouter.__init__',
4263
_wrapper
4364
)
65+
wrapt.wrap_function_wrapper(
66+
'starlette.applications',
67+
'Starlette.add_exception_handler',
68+
_exception_handler_wrapper
69+
)
70+
wrapt.wrap_function_wrapper(
71+
'starlette.middleware.errors',
72+
'ServerErrorMiddleware.__call__',
73+
server_call_wrapper
74+
)

epsagon/modules/tornado.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def thread_pool_submit(cls, func, _, args, kwargs):
208208

209209
try:
210210
trace = epsagon.trace.trace_factory.get_trace()
211-
if trace:
211+
if trace and trace.unique_id in cls.RUNNERS:
212212
unique_id = trace.unique_id
213213

214214
except Exception as instrumentation_exception: # pylint: disable=W0703

epsagon/runners/fastapi.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,13 @@ def _update_raw_response_body(self, response, response_type):
109109
)
110110

111111

112-
def _update_status_code(self, status_code):
112+
def update_status_code(self, status_code, override=True):
113113
"""
114114
Updates the event with given status code.
115+
:param override: indicates whether to override existing status code
115116
"""
117+
if self.resource['metadata'].get('status_code') and not override:
118+
return
116119
self.resource['metadata']['status_code'] = status_code
117120
if status_code and status_code >= 500:
118121
self.set_error()
@@ -134,7 +137,7 @@ def _update_raw_response(self, response):
134137
'Response Headers',
135138
response_headers
136139
)
137-
self._update_status_code(response.status_code)
140+
self.update_status_code(response.status_code)
138141

139142
def update_response(self, response, status_code=None):
140143
"""
@@ -154,4 +157,4 @@ def update_response(self, response, status_code=None):
154157
'Could not json encode fastapi handler response data'
155158
)
156159
if status_code:
157-
self._update_status_code(status_code)
160+
self.update_status_code(status_code)

epsagon/trace.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ def _get_thread_trace(self, should_create=False):
247247
:return: The trace.
248248
"""
249249
# If multiple threads are used, then create a new trace for each thread
250-
thread_id = self.get_trace_identifier()
250+
thread_id = get_thread_id()
251251
if thread_id not in self.traces:
252252
if not should_create:
253253
return None

0 commit comments

Comments
 (0)