Skip to content

[Feature]: Add error handlers that can catch an error from anywhere in the app #2054

@sebovzeoueb

Description

@sebovzeoueb

Category

Other

Scope

Minor Enhancement

Problem

I have quite a few different calls to an API client object in a fairly large app which is spread across multiple modules. I would like to be able to catch and handle a specific error raised by these calls without having to wrap every single call in a try...except and without having my app freeze.

I've enclosed some demo code which illustrates a way in which I attempted to achieve this, but of course it doesn't work because Shiny handles the errors internally rather than letting them raise up to the top level app.

from starlette.applications import Starlette
from starlette.routing import Mount
from starlette.responses import RedirectResponse

class TestException(Exception):
    pass

app_ui = ui.page_auto(ui.input_action_button("trigger_exception", "Trigger Exception"))

def server(input: Inputs, output: Outputs, session: Session):
    
    @reactive.effect
    @reactive.event(input.trigger_exception, ignore_init=True)
    def raise_exception():
        raise TestException()
        # this causes a ReactiveWarning to be logged to the console
        # I would like some way to handle this globally across the whole app instead of using a try...except in every single call that can raise this exception
        # In the real app it's a lot of functions
    
shiny_app = App(app_ui, server)

async def handle_test():
    # In an ideal world this would trigger when TestException is raised in the app
    return RedirectResponse("/login")

exception_handlers = {
    TestException: handle_test
}

routes = [
    Mount("/", app=shiny_app),
]

# This doesn't work because the code for reactives catches the exception and logs it to the console
app = Starlette(routes=routes, exception_handlers=exception_handlers)

Hopefully this clarifies what I was trying to achieve.

Solution

FastAPI and Starlette (as you can see in my example code above) both have exception handlers that work like I'm describing. In my case it would be really useful to be able to trigger a Starlette exception handler, but I can imagine that some people would want to be able to handle it within the UI layout itself, maybe there could be a way to decorate a function to render on error.

Alternatives (Optional)

No response

Example (Optional)

Impact (Optional)

No response

Contribution? (Optional)

None

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions