Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Falcon integration for Falcon 3.0.1 #1297

Merged
merged 5 commits into from
Nov 10, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
58 changes: 42 additions & 16 deletions sentry_sdk/integrations/falcon.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@
raise DidNotEnable("Falcon not installed")


# In Falcon 3.0 `falcon.api_helpers` is renamed to `falcon.app_helpers`
# and `falcon.API` to `falcon.App`
try:
import falcon.app # type: ignore
import falcon.app_helpers # type: ignore

falcon_helpers = falcon.app_helpers
falcon_app_class = falcon.App
FALCON3 = True
except ImportError:
falcon_helpers = falcon.api_helpers
falcon_app_class = falcon.API
FALCON3 = False


class FalconRequestExtractor(RequestExtractor):
def env(self):
# type: () -> Dict[str, Any]
Expand Down Expand Up @@ -58,16 +73,27 @@ def raw_data(self):
else:
return None

def json(self):
# type: () -> Optional[Dict[str, Any]]
try:
return self.request.media
except falcon.errors.HTTPBadRequest:
# NOTE(jmagnusson): We return `falcon.Request._media` here because
# falcon 1.4 doesn't do proper type checking in
# `falcon.Request.media`. This has been fixed in 2.0.
# Relevant code: https://github.com/falconry/falcon/blob/1.4.1/falcon/request.py#L953
return self.request._media
if FALCON3:

def json(self):
# type: () -> Optional[Dict[str, Any]]
try:
return self.request.media
except falcon.errors.HTTPBadRequest:
return None

else:

def json(self):
# type: () -> Optional[Dict[str, Any]]
try:
return self.request.media
except falcon.errors.HTTPBadRequest:
# NOTE(jmagnusson): We return `falcon.Request._media` here because
# falcon 1.4 doesn't do proper type checking in
# `falcon.Request.media`. This has been fixed in 2.0.
# Relevant code: https://github.com/falconry/falcon/blob/1.4.1/falcon/request.py#L953
return self.request._media


class SentryFalconMiddleware(object):
Expand Down Expand Up @@ -120,7 +146,7 @@ def setup_once():

def _patch_wsgi_app():
# type: () -> None
original_wsgi_app = falcon.API.__call__
original_wsgi_app = falcon_app_class.__call__

def sentry_patched_wsgi_app(self, env, start_response):
# type: (falcon.API, Any, Any) -> Any
Expand All @@ -135,12 +161,12 @@ def sentry_patched_wsgi_app(self, env, start_response):

return sentry_wrapped(env, start_response)

falcon.API.__call__ = sentry_patched_wsgi_app
falcon_app_class.__call__ = sentry_patched_wsgi_app


def _patch_handle_exception():
# type: () -> None
original_handle_exception = falcon.API._handle_exception
original_handle_exception = falcon_app_class._handle_exception

def sentry_patched_handle_exception(self, *args):
# type: (falcon.API, *Any) -> Any
Expand Down Expand Up @@ -170,12 +196,12 @@ def sentry_patched_handle_exception(self, *args):

return was_handled

falcon.API._handle_exception = sentry_patched_handle_exception
falcon_app_class._handle_exception = sentry_patched_handle_exception


def _patch_prepare_middleware():
# type: () -> None
original_prepare_middleware = falcon.api_helpers.prepare_middleware
original_prepare_middleware = falcon_helpers.prepare_middleware

def sentry_patched_prepare_middleware(
middleware=None, independent_middleware=False
Expand All @@ -187,7 +213,7 @@ def sentry_patched_prepare_middleware(
middleware = [SentryFalconMiddleware()] + (middleware or [])
return original_prepare_middleware(middleware, independent_middleware)

falcon.api_helpers.prepare_middleware = sentry_patched_prepare_middleware
falcon_helpers.prepare_middleware = sentry_patched_prepare_middleware


def _exception_leads_to_http_5xx(ex):
Expand Down