Skip to content
Open
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
10 changes: 8 additions & 2 deletions debug_toolbar/panels/settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.utils.encoding import force_str
from django.utils.encoding import DjangoUnicodeDecodeError, force_str
from django.utils.translation import gettext_lazy as _
from django.views.debug import get_default_exception_reporter_filter

Expand All @@ -24,10 +24,16 @@ def title(self):
)

def generate_stats(self, request, response):
def catch_force_errors(force_function, value):
try:
return force_function(value)
except DjangoUnicodeDecodeError:
return "Debug toolbar was unable to parse value"
Comment on lines +27 to +31
Copy link
Member

Choose a reason for hiding this comment

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

There are a few places we use force_str and I suspect we may want to swap all of them out with this new function. Perhaps we should create a sanitize.py file and put this in there with a doc string explaining the interface and what it does. Then use that everywhere we've been using force_str. I'd consider keeping the name as force_str too, but that's just my preference. We'd want to have an explicit test covering the functionality of this new function too.

There are some other sanitizing functions in utils.py that can be moved over too, though that should be a separate commit. Or I can do that.

Copy link
Member

@tim-schilling tim-schilling Oct 6, 2025

Choose a reason for hiding this comment

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

Suggested change
return "Debug toolbar was unable to parse value"
return "Django Debug Toolbar was unable to parse value."

nitpick: We use the full name in other messaging presented to users.


self.record_stats(
{
"settings": {
key: force_str(value)
key: catch_force_errors(force_str, value)
for key, value in sorted(get_safe_settings().items())
}
}
Expand Down
2 changes: 2 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Pending
class instance, regardless if any data was generated.
* Fixed selenium tests for CI by using psycopg for Python 3.13 runs.
* Added ``CommunityPanel`` containing links to documentation and resources.
* Fixed force_str to catch error and give out default string if value is not
serializable.
Comment on lines +16 to +17
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Fixed force_str to catch error and give out default string if value is not
serializable.
* Updated logic that forces values to strings to render "Django Debug Toolbar was
unable to parse value." when there's a decoding error.

I think we're better off trying to communicate what is going to change from a developer experience here rather than what technically changed. A user may try to figure out why they are getting this message and our documentation may not explain it. Having it here in the change log will help them realize it's intentional and be able to track what the issue/PR is to see why it was changed.


6.0.0 (2025-07-22)
------------------
Expand Down
7 changes: 6 additions & 1 deletion tests/panels/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
from ..base import IntegrationTestCase


@override_settings(DEBUG=True)
@override_settings(
DEBUG=True,
RANDOM_SETTING=bytes.fromhex(
"a3f2b8c14e972d5a8fb3c7291a64e0859c472bf63d18a0945e73b2c84f917ae2"
),
)
class SettingsIntegrationTestCase(IntegrationTestCase):
def test_panel_title(self):
response = self.client.get("/regular/basic/")
Expand Down