Skip to content
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
Empty file added .git-blame-ignore-revs
Empty file.
3 changes: 2 additions & 1 deletion debug_toolbar/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from django import forms
from django.core import signing
from django.core.exceptions import ValidationError
from django.utils.encoding import force_str

from debug_toolbar.sanitize import force_str


class SignedDataForm(forms.Form):
Expand Down
2 changes: 1 addition & 1 deletion debug_toolbar/panels/settings.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from django.utils.encoding import force_str
from django.utils.translation import gettext_lazy as _
from django.views.debug import get_default_exception_reporter_filter

from debug_toolbar.panels import Panel
from debug_toolbar.sanitize import force_str

get_safe_settings = get_default_exception_reporter_filter().get_safe_settings

Expand Down
7 changes: 2 additions & 5 deletions debug_toolbar/panels/sql/tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from time import perf_counter

import django.test.testcases
from django.utils.encoding import force_str

from debug_toolbar.sanitize import force_str
from debug_toolbar.utils import get_stack_trace, get_template_info

try:
Expand Down Expand Up @@ -128,10 +128,7 @@ def _decode(self, param):

# make sure datetime, date and time are converted to string by force_str
CONVERT_TYPES = (datetime.datetime, datetime.date, datetime.time)
try:
return force_str(param, strings_only=not isinstance(param, CONVERT_TYPES))
except UnicodeDecodeError:
return "(encoded string)"
return force_str(param, strings_only=not isinstance(param, CONVERT_TYPES))

def _last_executed_query(self, sql, params):
"""Get the last executed query from the connection."""
Expand Down
2 changes: 1 addition & 1 deletion debug_toolbar/panels/templates/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
from django.test.signals import template_rendered
from django.test.utils import instrumented_test_render
from django.urls import path
from django.utils.encoding import force_str
from django.utils.translation import gettext_lazy as _

from debug_toolbar.panels import Panel
from debug_toolbar.panels.sql.tracking import SQLQueryTriggered, allow_sql
from debug_toolbar.panels.templates import views
from debug_toolbar.sanitize import force_str

if find_spec("jinja2"):
from debug_toolbar.panels.templates.jinja2 import patch_jinja_render
Expand Down
12 changes: 12 additions & 0 deletions debug_toolbar/sanitize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.utils.encoding import DjangoUnicodeDecodeError, force_str as force_string


def force_str(s, *args, **kwargs):
"""
Forces values to strings.
Will return "Django Debug Toolbar was unable to parse value." when there's a decoding error.
"""
try:
return force_string(s, *args, **kwargs)
except DjangoUnicodeDecodeError:
return "Django Debug Toolbar was unable to parse value."
2 changes: 1 addition & 1 deletion debug_toolbar/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

from django.core.serializers.json import DjangoJSONEncoder
from django.db import transaction
from django.utils.encoding import force_str
from django.utils.module_loading import import_string

from debug_toolbar import settings as dt_settings
from debug_toolbar.models import HistoryEntry
from debug_toolbar.sanitize import force_str


class DebugToolbarJSONEncoder(DjangoJSONEncoder):
Expand Down
3 changes: 3 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ Pending
* Upgraded CI ``postgis`` version to 17-3.5.
* Added how to generate the documentation locally to the contributing
documentation.
* Updated logic that forces values to strings (``force_str``) to render
"Django Debug Toolbar was unable to parse value." when there's a decoding
error.

6.0.0 (2025-07-22)
------------------
Expand Down
18 changes: 18 additions & 0 deletions tests/test_sanitize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import unittest

from debug_toolbar.sanitize import force_str


class ForceStrTestCase(unittest.TestCase):
def test_success_convert(self):
input = 0

self.assertEqual(force_str(input), "0")

def test_failed_convert(self):
input = bytes.fromhex(
"a3f2b8c14e972d5a8fb3c7291a64e0859c472bf63d18a0945e73b2c84f917ae2"
)
self.assertEqual(
force_str(input), "Django Debug Toolbar was unable to parse value."
)