Py.Cafe

egormkn/

witty-weapon

Exception Handler Using Solara

DocsPricing
  • app.py
  • requirements.txt
app.py
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
import traceback
from typing import Iterable

import reacton
import reacton.ipyvuetify as rv
import solara
from IPython.display import HTML, display
from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import PythonTracebackLexer


traceback_lexer = PythonTracebackLexer()
html_formatter = HtmlFormatter(style="default", noclasses=True, nobackground=True)


@reacton.component
def UnstableComponent(number: int):
    if number == 3:
        raise Exception("I do not like 3")
    return rv.Html(tag="span", children=[f"You picked {number}"])


@reacton.component
def ErrorCard(*, error: BaseException, actions: Iterable[reacton.core.Element] = (), **kwargs):
    def get_html():
        title = traceback.format_exception_only(error)[-1]
        content = "".join(traceback.format_exception(error))
        html = highlight(content, traceback_lexer, html_formatter)
        return title, html

    title, html = reacton.use_memo(get_html, dependencies=[error])

    with rv.ExpansionPanels(**kwargs) as card:
        with rv.ExpansionPanel(class_="error"):
            rv.ExpansionPanelHeader(
                children=[title],
                v_slots=[{"name": "actions", "children": actions}] if actions else [],
            )
            with rv.ExpansionPanelContent(eager=False):
                display(HTML(html))

    return card


@reacton.component
def ResetButton(on_reset):
    reset_button = rv.Btn(children=["Reset"])

    rv.use_event(reset_button, "click.stop", lambda *args: on_reset())

    return reset_button


@reacton.component
def Page():
    value, set_value = reacton.use_state(1)
    previous_value = solara.use_previous(value)
    exception, clear_exception = solara.use_exception()

    def reset():
        set_value(previous_value)
        clear_exception()

    if exception:
        return ErrorCard(error=exception, actions=[ResetButton(on_reset=reset)])

    with rv.Card() as card:
        with rv.CardText():
            rv.Slider(v_model=value, on_v_model=set_value, min=0, max=10, label="Pick a number, except 3")
            UnstableComponent(value)

    return card