Skip to content

Commit 5e89d95

Browse files
committed
Add fallback traceback formatting.
1 parent 8c198b4 commit 5e89d95

File tree

2 files changed

+33
-14
lines changed

2 files changed

+33
-14
lines changed

dash/_utils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import logging
99
import io
1010
import json
11+
import secrets
12+
import string
1113
from functools import wraps
1214

1315
logger = logging.getLogger()
@@ -206,3 +208,9 @@ def _wrapper(*args, **kwargs):
206208
return _wrapper
207209

208210
return wrapper
211+
212+
213+
def gen_salt(chars):
214+
return "".join(
215+
secrets.choice(string.ascii_letters + string.digits) for _ in range(chars)
216+
)

dash/dash.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@
1111
import mimetypes
1212
import hashlib
1313
import base64
14+
import traceback
1415
from urllib.parse import urlparse
1516

1617
import flask
1718
from flask_compress import Compress
1819

19-
from werkzeug.debug import tbtools
20-
from werkzeug.security import gen_salt
21-
2220
from pkg_resources import get_distribution, parse_version
2321
from dash import dcc
2422
from dash import html
@@ -51,6 +49,7 @@
5149
patch_collections_abc,
5250
split_callback_id,
5351
to_json,
52+
gen_salt,
5453
)
5554
from . import _callback
5655
from . import _get_paths
@@ -105,28 +104,40 @@
105104
_re_renderer_scripts_id = 'id="_dash-renderer', "new DashRenderer"
106105

107106

108-
def _get_traceback(secret, error):
109-
def _get_skip(text):
107+
def _get_traceback(secret, error: Exception):
108+
109+
try:
110+
# pylint: disable=import-outside-toplevel
111+
from werkzeug.debug import tbtools
112+
except ImportError:
113+
tbtools = None
114+
115+
def _get_skip(text, divider=2):
110116
skip = 0
111-
for i, line in enumerate(text.splitlines()):
117+
for i, line in enumerate(text):
112118
if "%% callback invoked %%" in line:
113-
skip = int((i + 1) / 2)
119+
skip = int((i + 1) / divider)
114120
break
115121
return skip
116122

117123
# werkzeug<2.1.0
118124
if hasattr(tbtools, "get_current_traceback"):
119125
tb = tbtools.get_current_traceback()
120-
skip = _get_skip(tb.plaintext)
126+
skip = _get_skip(tb.plaintext.splitlines())
121127
return tbtools.get_current_traceback(skip=skip).render_full()
122128

123-
tb = tbtools.DebugTraceback(error) # pylint: disable=no-member
124-
skip = _get_skip(tb.render_traceback_text())
129+
if hasattr(tbtools, "DebugTraceback"):
130+
tb = tbtools.DebugTraceback(error) # pylint: disable=no-member
131+
skip = _get_skip(tb.render_traceback_text().splitlines())
132+
133+
# pylint: disable=no-member
134+
return tbtools.DebugTraceback(error, skip=skip).render_debugger_html(
135+
True, secret, True
136+
)
125137

126-
# pylint: disable=no-member
127-
return tbtools.DebugTraceback(error, skip=skip).render_debugger_html(
128-
True, secret, True
129-
)
138+
tb = traceback.format_exception(type(error), error, error.__traceback__)
139+
skip = _get_skip(tb, 1)
140+
return tb[0] + "".join(tb[skip:])
130141

131142

132143
class _NoUpdate:

0 commit comments

Comments
 (0)