Skip to content

Conversation

jacobtylerwalls
Copy link
Member

@jacobtylerwalls jacobtylerwalls commented Sep 18, 2025

Trac ticket number

ticket-26886 ticket-28526

Branch description

Before, the technical 404 view was written in a way that interrogates a possibly missing .name on a url pattern or resolver. .name only exists on URLPattern.

Now, we log something else helpful for URLResolver, namely .namespace. This takes care of the huge traceback cited in the issue.

A custom template tag might have been a nicer implementation than what I ended up with, but the technical 404 template is not inside an app, so we can't register a custom tag AFIACT.

Checklist

  • This PR targets the main branch.
  • The commit message is written in past tense, mentions the ticket number, and ends with a period.
  • I have checked the "Has patch" ticket flag in the Trac system.
  • I have added or updated relevant tests.
  • I have added or updated relevant docs, including release notes if applicable.
  • I have attached screenshots in both light and dark modes for any UI changes.

@sarahboyce sarahboyce changed the title Fixed #26886 -- Provided URLResolver namespace in technical 404 template. Refs #28526 -- Provided URLResolver namespace in technical 404 template. Sep 24, 2025
Copy link
Contributor

@sarahboyce sarahboyce left a comment

Choose a reason for hiding this comment

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

Thank you! I have minor comments

Comment on lines 640 to 647
if isinstance(inner_tried, URLResolver):
inner_tried.debug_key_val = TriedPatternDebugInfo(
key="namespace", val=inner_tried.namespace
)
else:
inner_tried.debug_key_val = TriedPatternDebugInfo(
key="name", val=inner_tried.name
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if isinstance(inner_tried, URLResolver):
inner_tried.debug_key_val = TriedPatternDebugInfo(
key="namespace", val=inner_tried.namespace
)
else:
inner_tried.debug_key_val = TriedPatternDebugInfo(
key="name", val=inner_tried.name
)
if isinstance(inner_tried, URLResolver):
inner_tried.debug_key_val = {
"key": "namespace",
"val": inner_tried.namespace,
}
else:
inner_tried.debug_key_val = {"key": "name", "val": inner_tried.name}

I wouldn't add a namedtuple unless we had to

Copy link
Member

Choose a reason for hiding this comment

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

Agree, I think it's pretty idiomatic to pass dicts into templates.

Copy link
Member Author

Choose a reason for hiding this comment

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

Terrific. Haven't written a template in a long time and simply forgot this was possible!

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't love that I'm polluting the underlying object, will look into adding wrappers. Would have been a lot easier if I could have registered a filter?

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed pollution in latest.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, that looks better.

Comment on lines 426 to 429
@override_settings(ROOT_URLCONF="view_tests.default_urls")
def test_default_urlconf_template_404(self):
response = self.client.get("/favicon.ico")
self.assertContains(response, "[namespace='admin']", status_code=404)
Copy link
Contributor

Choose a reason for hiding this comment

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

I tried to find if we could make a test a bit closer to the issue but I wasn't successful
Have tested manually that the issue is fixed and that this covered the code changes 👍

Copy link
Member

Choose a reason for hiding this comment

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

Can you use assertInHTML and check for the full contents of the <code> tag? I think that would be a little bit clearer for future readers.

Comment on lines 426 to 429
@override_settings(ROOT_URLCONF="view_tests.default_urls")
def test_default_urlconf_template_404(self):
response = self.client.get("/favicon.ico")
self.assertContains(response, "[namespace='admin']", status_code=404)
Copy link
Member

Choose a reason for hiding this comment

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

Can you use assertInHTML and check for the full contents of the <code> tag? I think that would be a little bit clearer for future readers.

Comment on lines 640 to 647
if isinstance(inner_tried, URLResolver):
inner_tried.debug_key_val = TriedPatternDebugInfo(
key="namespace", val=inner_tried.namespace
)
else:
inner_tried.debug_key_val = TriedPatternDebugInfo(
key="name", val=inner_tried.name
)
Copy link
Member

Choose a reason for hiding this comment

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

Agree, I think it's pretty idiomatic to pass dicts into templates.

Comment on lines 650 to 664
"urlpatterns": tried,
"urlpatterns": patterns_with_debug_info,
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know whether we need to be concerned or not but we could add urlpatterns_debug to the context and leave urlpatterns alone or make sure that the structure of urlpatterns is backwards compatible for if someone was overwriting the technical_404.html template

This avoids looking up the nonexistent "name" attribute on URLResolver,
which logs verbosely.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants