Skip to content

fix(django): Attempt custom urlconf resolve in got_request_exception as well #1317

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

Merged
merged 2 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions sentry_sdk/integrations/django/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
from django.http.request import QueryDict
from django.utils.datastructures import MultiValueDict

from sentry_sdk.scope import Scope
from sentry_sdk.integrations.wsgi import _ScopedResponse
from sentry_sdk._types import Event, Hint, EventProcessor, NotImplementedType

Expand Down Expand Up @@ -346,8 +347,8 @@ def _before_get_response(request):
)


def _after_get_response(request):
# type: (WSGIRequest) -> None
def _attempt_resolve_again(request, scope):
# type: (WSGIRequest, Scope) -> None
"""
Some django middlewares overwrite request.urlconf
so we need to respect that contract,
Expand All @@ -356,19 +357,24 @@ def _after_get_response(request):
if not hasattr(request, "urlconf"):
return

try:
scope.transaction = LEGACY_RESOLVER.resolve(
request.path_info,
urlconf=request.urlconf,
)
except Exception:
pass


def _after_get_response(request):
# type: (WSGIRequest) -> None
hub = Hub.current
integration = hub.get_integration(DjangoIntegration)
if integration is None or integration.transaction_style != "url":
return

with hub.configure_scope() as scope:
try:
scope.transaction = LEGACY_RESOLVER.resolve(
request.path_info,
urlconf=request.urlconf,
)
except Exception:
pass
_attempt_resolve_again(request, scope)


def _patch_get_response():
Expand Down Expand Up @@ -431,6 +437,10 @@ def _got_request_exception(request=None, **kwargs):
integration = hub.get_integration(DjangoIntegration)
if integration is not None:

if request is not None and integration.transaction_style == "url":
with hub.configure_scope() as scope:
_attempt_resolve_again(request, scope)

# If an integration is there, a client has to be there.
client = hub.client # type: Any

Expand Down
1 change: 1 addition & 0 deletions tests/integrations/django/myapp/custom_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ def path(path, *args, **kwargs):

urlpatterns = [
path("custom/ok", views.custom_ok, name="custom_ok"),
path("custom/exc", views.custom_exc, name="custom_exc"),
]
5 changes: 5 additions & 0 deletions tests/integrations/django/myapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ def custom_ok(request, *args, **kwargs):
return HttpResponse("custom ok")


@csrf_exempt
def custom_exc(request, *args, **kwargs):
1 / 0


@csrf_exempt
def template_test2(request, *args, **kwargs):
return TemplateResponse(
Expand Down
11 changes: 10 additions & 1 deletion tests/integrations/django/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -777,8 +777,17 @@ def test_custom_urlconf_middleware(
assert status.lower() == "200 ok"
assert b"".join(content) == b"custom ok"

(event,) = events
event = events.pop(0)
assert event["transaction"] == "/custom/ok"
assert "custom_urlconf_middleware" in render_span_tree(event)

_content, status, _headers = client.get("/custom/exc")
assert status.lower() == "500 internal server error"

error_event, transaction_event = events
assert error_event["transaction"] == "/custom/exc"
assert error_event["exception"]["values"][-1]["mechanism"]["type"] == "django"
assert transaction_event["transaction"] == "/custom/exc"
assert "custom_urlconf_middleware" in render_span_tree(transaction_event)

settings.MIDDLEWARE.pop(0)