-
I wrote a
I'm not sure it acts entirely transparently (besides the interposed div element and such), i.e. could it alter the rendering logic of the wrapped component [Edit: I observe that it's not 'transparent' but don't know why.] Thank you. def debug_component(f):
def _(*a, **kw):
@idom_component
def _f(*a, **kw):
try:
return f(*a, **kw)
except Exception as e:
log.exception(e)
return html.div(
{
'className': "alert alert-danger",
},
f"{e.__class__.__name__}: {e}"
)
uuid = uuid4().hex
return html.div(
{
'id': f"debug-{uuid}-container",
'style': {
'border': "1px dashed rgba(0, 0, 0, .1)",
'margin': "-1px",
},
},
html.div(
{
'className': "text-muted",
'style': {
'fontSize': "0.3em",
},
},
html.iframe(
{
'name': f"debug-{uuid}-frame",
'hidden': True,
},
),
html.a(
{
'id': f"debug-{uuid}-link",
'href': pycharm_reverse_link(f),
'target': f"debug-{uuid}-frame",
},
f"Rendered at: {datetime.datetime.now()}",
),
),
html.script(
string.Template(""" $("#${container_id}").on("click", function(e) {
if (!e.altKey) return
let a = $("#${link_id}").get(0)
if (a) a.click()
e.stopPropagation()
e.preventDefault()
return false
}); """).safe_substitute(
container_id=f"debug-{uuid}-container",
link_id=f"debug-{uuid}-link",
)
),
html.div(
_f(*a, **kw)
),
)
return _ For completeness, this is how reverse-navigation works (Ubuntu + PyCharm + non-snap-Firefox): Construct "URL": def pycharm_reverse_link(f):
return f"pycharm: --line {f.__code__.co_firstlineno} {f.__code__.co_filename}" In executable file ~/.pycharm.sh: #!/bin/bash
app="pycharm-community"
protocol="pycharm:"
args=${1#"$protocol"}
# https://stackoverflow.com/a/70560850
urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
echo Running: $app $(urldecode "$args") >> ~/.pycharm.sh.log
$app $(urldecode "$args") In file ~/.local/share/applications/pycharm.desktop: [Desktop Entry]
Type=Application
Encoding=UTF-8
Name=PyCharm-Custom
Exec=/path/to/user/home/.pycharm.sh %u
Icon=/snap/pycharm-community/current/meta/gui/icon.png
Terminal=false
MimeType=x-scheme-handler/pycharm |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
For this to be transparent you just need to ensure two things:
You can ensure 1 by declaring the "error" view in a separate component to isolate any state it might have. You can fulfill 2 by either returning elements with different keys, or components of different "types" where two components may be said to have the differing types if they came from distinct functions. Here's an example that implements this from idom import component
class safe_component:
def __init__(self, render_view):
self.render_view = render_view
self.render_error = None
@component
def __call__(self, *args, **kwargs):
try:
return self.render_view(*args, **kwargs)
except Exception as error:
if not self.render_error:
raise
return self.render_error(error, *args, **kwargs)
def on_error(self, render_error):
assert self.render_view is not render_error
# ensure state declared by render_error is isolated
self.render_error = component(render_error)
return render_error With usage like: @safe_component
def example():
raise Exception("error")
@example.on_error
def example_error(error):
... |
Beta Was this translation helpful? Give feedback.
-
With all that said, React has a concept of "error boundaries" that do not exist in IDOM yet. |
Beta Was this translation helpful? Give feedback.
For this to be transparent you just need to ensure two things:
You can ensure 1 by declaring the "error" view in a separate component to isolate any state it might have. You can fulfill 2 by either returning elements with different keys, or components of different "types" where two components may be said to have the differing types if they came from distinct functions. Here's an example that implements this