Skip to content

Commit a31115f

Browse files
committed
Force everything to a string if it can't be serialized.
The alternative here is to inspect and iterate over every collection and object passed around. This avoids having to reinvent the wheel in that scenario.
1 parent 14a5e0c commit a31115f

File tree

5 files changed

+12
-38
lines changed

5 files changed

+12
-38
lines changed

debug_toolbar/settings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
"PROFILER_CAPTURE_PROJECT_CODE": True,
3838
"PROFILER_MAX_DEPTH": 10,
3939
"PROFILER_THRESHOLD_RATIO": 8,
40-
"SUPPRESS_SERIALIZATION_ERRORS": True,
4140
"SHOW_TEMPLATE_CONTEXT": True,
4241
"SKIP_TEMPLATE_PREFIXES": ("django/forms/widgets/", "admin/widgets/"),
4342
"SQL_WARNING_THRESHOLD": 500, # milliseconds

debug_toolbar/store.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,28 @@
55
from typing import Any, Dict, Iterable
66

77
from django.core.serializers.json import DjangoJSONEncoder
8+
from django.utils.encoding import force_str
89
from django.utils.module_loading import import_string
910

1011
from debug_toolbar import settings as dt_settings
1112

1213
logger = logging.getLogger(__name__)
1314

1415

16+
class DebugToolbarJSONEncoder(DjangoJSONEncoder):
17+
def default(self, o):
18+
try:
19+
return super().default(o)
20+
except (TypeError, ValueError):
21+
logger.debug("The debug toolbar can't serialize %s into JSON" % o)
22+
return force_str(o)
23+
24+
1525
def serialize(data: Any) -> str:
1626
# If this starts throwing an exceptions, consider
1727
# Subclassing DjangoJSONEncoder and using force_str to
1828
# make it JSON serializable.
19-
return json.dumps(data, cls=DjangoJSONEncoder)
29+
return json.dumps(data, cls=DebugToolbarJSONEncoder)
2030

2131

2232
def deserialize(data: str) -> Any:
@@ -106,14 +116,7 @@ def delete(cls, request_id: str):
106116
def save_panel(cls, request_id: str, panel_id: str, data: Any = None):
107117
"""Save the panel data for the given request_id"""
108118
cls.set(request_id)
109-
try:
110-
cls._request_store[request_id][panel_id] = serialize(data)
111-
except TypeError:
112-
if dt_settings.get_config()["SUPPRESS_SERIALIZATION_ERRORS"]:
113-
log = "Panel (%s) failed to serialized data %s properly."
114-
logger.warning(log % (panel_id, data))
115-
else:
116-
raise
119+
cls._request_store[request_id][panel_id] = serialize(data)
117120

118121
@classmethod
119122
def panel(cls, request_id: str, panel_id: str) -> Any:

docs/changes.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ Serializable (don't include in main)
77
* Defines the ``BaseStore`` interface for request storage mechanisms.
88
* Added the setting ``TOOLBAR_STORE_CLASS`` to configure the request
99
storage mechanism. Defaults to ``debug_toolbar.store.MemoryStore``.
10-
* Added setting ``SUPPRESS_SERIALIZATION_ERRORS`` to suppress
11-
warnings when a ``TypeError`` occurs during a panel's serialization.
1210
* Rename ``store_id`` properties to ``request_id`` and ``Toolbar.store`` to
1311
``Toolbar.init_store``.
1412
* Support ``Panel`` instances with stored stats via

docs/configuration.rst

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -306,15 +306,6 @@ Panel options
306306
the nested functions. The threshold is calculated by the root calls'
307307
cumulative time divided by this ratio.
308308

309-
* ``SUPPRESS_SERIALIZATION_ERRORS``
310-
311-
Default: ``True``
312-
313-
If set to ``True`` then panels will log a warning if a ``TypeError`` is
314-
raised when attempting to serialize a panel's stats rather than raising an
315-
exception.. If set to ``False`` then the ``TypeError`` will be raised. The
316-
default will eventually be set to ``False`` and removed entirely.
317-
318309
* ``SHOW_TEMPLATE_CONTEXT``
319310

320311
Default: ``True``

tests/test_store.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import logging
2-
31
from django.test import TestCase
42
from django.test.utils import override_settings
53

@@ -95,21 +93,6 @@ def test_save_panel(self):
9593
self.assertEqual(list(self.store.request_ids()), ["bar"])
9694
self.assertEqual(self.store.panel("bar", "bar.panel"), {"a": 1})
9795

98-
def test_save_panel_serialization_warning(self):
99-
"""The store should warn the user about a serialization error."""
100-
self.assertLogs()
101-
102-
with self.assertLogs("debug_toolbar.store", level=logging.WARNING) as logs:
103-
self.store.save_panel("bar", "bar.panel", {"value": {"foo"}})
104-
105-
self.assertEqual(
106-
logs.output,
107-
[
108-
"WARNING:debug_toolbar.store:Panel (bar.panel) failed to "
109-
"serialized data {'value': {'foo'}} properly."
110-
],
111-
)
112-
11396
def test_panel(self):
11497
self.assertEqual(self.store.panel("missing", "missing"), {})
11598
self.store.save_panel("bar", "bar.panel", {"a": 1})

0 commit comments

Comments
 (0)