Skip to content

Conversation

@untitaker
Copy link
Member

@untitaker untitaker commented May 23, 2020

Found multiple issues with the asgi middleware:

  • lack of warning if contextvars are broken -- as part of that I refactored/unified the error message we give in such situations, also added more information as gevent just recently released a version that deals with contextvars better
  • exposed methods that were meant for overriding.. but all that is done in there can be done in event processors, so we make them private

Fix #630
Fix #700
Fix #694

@untitaker untitaker requested a review from rhcarvalho May 23, 2020 20:47
if client and _should_send_default_pii():
request_info["env"] = {"REMOTE_ADDR": client[0]}

if event.get("transaction", TRANSACTION_SENTINEL) == TRANSACTION_SENTINEL:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this to allow users to actually override the transaction in their own code which previously was not possible.

return True, ContextVar
except ImportError:
pass
else:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is necessary as a bare contextvars installation from PyPI on Python 3.6 is totally useless for our purposes, in those cases we do want to return HAS_REAL_CONTEXTVARS = False

Copy link
Contributor

@rhcarvalho rhcarvalho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @untitaker!

  • I'm concerned that renaming/removing implicitly public methods now could break users. Do we follow a different stability guarantee in integrations?

Other than the above, you have my approval.

  • The part related to #700 seems clear and obvious. My only suggestion is adding a test case to avoid regression. Up to your decision.

  • How this is fixing #630 and #694 is a bit more nuanced. I understood part of fixing #694 is the more thorough error message and HAS_REAL_CONTEXTVARS = False. For #630 is the error message documenting the situation better.

request_info["query_string"] = self.get_query(asgi_scope)
ty = asgi_scope["type"]
if ty in ("http", "websocket"):
request_info["method"] = asgi_scope.get("method")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 this fixes #700

Shall we add a test case to cover this against regression?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you consider this?

Copy link
Member Author

@untitaker untitaker May 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did add a test to ensure websocket applications using that middleware do not crash. There are some issues with websockets crash reporting that I think I need to investigate separately.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test did not bother whether we do asgi.scope["method"] (the original problem from #700) or asgi.scope.get("method") (the minimal fix, I believe):

$ git df -- sentry_sdk/integrations/                                                                                                       ref/asgi ✭ ✱ ◼
diff --git a/sentry_sdk/integrations/asgi.py b/sentry_sdk/integrations/asgi.py
index 202c490..d9e247f 100644
--- a/sentry_sdk/integrations/asgi.py
+++ b/sentry_sdk/integrations/asgi.py
@@ -150,7 +150,7 @@ class SentryAsgiMiddleware:

         ty = asgi_scope["type"]
         if ty in ("http", "websocket"):
-            request_info["method"] = asgi_scope.get("method")
+            request_info["method"] = asgi_scope["method"]
             request_info["headers"] = headers = _filter_headers(
                 self._get_headers(asgi_scope)
             )
$ pytest -k websocket ./tests/integrations/asgi/                                                                                           ref/asgi ✭ ✱ ◼
================================================================================ test session starts =================================================================================
platform darwin -- Python 3.7.7, pytest-3.7.3, py-1.8.1, pluggy-0.13.1
rootdir: /Users/rodolfo/sentry/sentry-python, inifile: pytest.ini
plugins: localserver-0.5.0, forked-1.1.3, cov-2.8.1
collected 4 items / 3 deselected

tests/integrations/asgi/test_asgi.py .                                                                                                                                         [100%]

======================================================================= 1 passed, 3 deselected in 0.13 seconds =======================================================================

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, thanks for catching that! I figured out why I was not able to get events through too so the test should be good now.

@rhcarvalho rhcarvalho self-requested a review May 25, 2020 11:25
Copy link
Contributor

@rhcarvalho rhcarvalho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a 0.x release, it is okay to note the breaking changes in the changelog and move on. For the other suggestions, I leave it up to @untitaker do decide what to do in the scope of this PR or not.

@untitaker
Copy link
Member Author

I think I addressed all feedback, please check again

installation of `contextvars` to avoid leaking scope/context data across
requests.

Please refer to https://docs.sentry.io/platforms/python/contextvars/ for more information.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

request_info["query_string"] = self.get_query(asgi_scope)
ty = asgi_scope["type"]
if ty in ("http", "websocket"):
request_info["method"] = asgi_scope.get("method")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you consider this?

@untitaker untitaker merged commit 36ed64e into master Jun 3, 2020
@untitaker untitaker deleted the ref/asgi branch June 3, 2020 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants