|
11 | 11 | import mimetypes
|
12 | 12 | import hashlib
|
13 | 13 | import base64
|
| 14 | +import traceback |
14 | 15 | from urllib.parse import urlparse
|
15 | 16 |
|
16 | 17 | import flask
|
17 | 18 | from flask_compress import Compress
|
18 | 19 |
|
19 |
| -from werkzeug.debug import tbtools |
20 |
| -from werkzeug.security import gen_salt |
21 |
| - |
22 | 20 | from pkg_resources import get_distribution, parse_version
|
23 | 21 | from dash import dcc
|
24 | 22 | from dash import html
|
|
51 | 49 | patch_collections_abc,
|
52 | 50 | split_callback_id,
|
53 | 51 | to_json,
|
| 52 | + gen_salt, |
54 | 53 | )
|
55 | 54 | from . import _callback
|
56 | 55 | from . import _get_paths
|
|
105 | 104 | _re_renderer_scripts_id = 'id="_dash-renderer', "new DashRenderer"
|
106 | 105 |
|
107 | 106 |
|
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): |
110 | 116 | skip = 0
|
111 |
| - for i, line in enumerate(text.splitlines()): |
| 117 | + for i, line in enumerate(text): |
112 | 118 | if "%% callback invoked %%" in line:
|
113 |
| - skip = int((i + 1) / 2) |
| 119 | + skip = int((i + 1) / divider) |
114 | 120 | break
|
115 | 121 | return skip
|
116 | 122 |
|
117 | 123 | # werkzeug<2.1.0
|
118 | 124 | if hasattr(tbtools, "get_current_traceback"):
|
119 | 125 | tb = tbtools.get_current_traceback()
|
120 |
| - skip = _get_skip(tb.plaintext) |
| 126 | + skip = _get_skip(tb.plaintext.splitlines()) |
121 | 127 | return tbtools.get_current_traceback(skip=skip).render_full()
|
122 | 128 |
|
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 | + ) |
125 | 137 |
|
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:]) |
130 | 141 |
|
131 | 142 |
|
132 | 143 | class _NoUpdate:
|
|
0 commit comments