1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
From f9079bfd8a9576947655e1fee0dc343171c21e37 Mon Sep 17 00:00:00 2001
From: philippe <t4rk@outlook.com>
Date: Tue, 29 Mar 2022 12:17:40 -0400
Subject: [PATCH] Fix werkzeug 2.1.0 import & dev tools error html rendering.
---
.../error/FrontEnd/FrontEndError.react.js | 2 +-
dash/dash.py | 42 +++++++++++++++----
2 files changed, 34 insertions(+), 10 deletions(-)
diff --git a/dash/dash-renderer/src/components/error/FrontEnd/FrontEndError.react.js b/dash/dash-renderer/src/components/error/FrontEnd/FrontEndError.react.js
index 5703add4..49939ea1 100644
--- a/dash/dash-renderer/src/components/error/FrontEnd/FrontEndError.react.js
+++ b/dash/dash-renderer/src/components/error/FrontEnd/FrontEndError.react.js
@@ -110,7 +110,7 @@ function UnconnectedErrorContent({error, base}) {
)}
{/* Backend Error */}
{typeof error.html !== 'string' ? null : error.html.indexOf(
- '<!DOCTYPE HTML'
+ '<!DOCTYPE'
) === 0 ? (
<div className='dash-be-error__st'>
<div className='dash-backend-error'>
diff --git a/dash/dash.py b/dash/dash.py
index b4a3adf0..3d5dae25 100644
--- a/dash/dash.py
+++ b/dash/dash.py
@@ -19,7 +19,10 @@ from future.moves.urllib.parse import urlparse
import flask
from flask_compress import Compress
-from werkzeug.debug.tbtools import get_current_traceback
+
+from werkzeug.debug import tbtools
+from werkzeug.security import gen_salt
+
from pkg_resources import get_distribution, parse_version
import plotly
@@ -91,6 +94,30 @@ _re_index_scripts_id = 'src="[^"]*dash[-_]renderer[^"]*"', "dash-renderer"
_re_renderer_scripts_id = 'id="_dash-renderer', "new DashRenderer"
+def _get_traceback(secret, error):
+ def _get_skip(text):
+ skip = 0
+ for i, line in enumerate(text.splitlines()):
+ if "%% callback invoked %%" in line:
+ skip = int((i + 1) / 2)
+ break
+ return skip
+
+ # werkzeug<2.1.0
+ if hasattr(tbtools, "get_current_traceback"):
+ tb = tbtools.get_current_traceback()
+ skip = _get_skip(tb.plaintext)
+ return tbtools.get_current_traceback(skip=skip).render_full()
+
+ tb = tbtools.DebugTraceback(error) # pylint: disable=no-member
+ skip = _get_skip(tb.render_traceback_text())
+
+ # pylint: disable=no-member
+ return tbtools.DebugTraceback(error, skip=skip).render_debugger_html(
+ True, secret, True
+ )
+
+
class _NoUpdate(object):
# pylint: disable=too-few-public-methods
pass
@@ -1463,19 +1490,16 @@ class Dash(object):
if debug and dev_tools.prune_errors:
+ secret = gen_salt(20)
+
@self.server.errorhandler(Exception)
- def _wrap_errors(_):
+ def _wrap_errors(error):
# find the callback invocation, if the error is from a callback
# and skip the traceback up to that point
# if the error didn't come from inside a callback, we won't
# skip anything.
- tb = get_current_traceback()
- skip = 0
- for i, line in enumerate(tb.plaintext.splitlines()):
- if "%% callback invoked %%" in line:
- skip = int((i + 1) / 2)
- break
- return get_current_traceback(skip=skip).render_full(), 500
+ tb = _get_traceback(secret, error)
+ return tb, 500
if debug and dev_tools.ui:
--
2.35.1
|