How to capture ProtocolError("Token is expired.") and offer notification

I find if I leave a panel served web app open for several hours; when I return to it, I see all the panes / widgets blank like the screenshot below.

In the log I see a bokeh error “Token is expired”.

[2023-12-01 22:26:26,903 |  INFO | tornado.access] 101 GET /My_App/ws?theme=dark (172.30.0.8) 1.36ms
[2023-12-01 22:26:26,903 |  INFO | bokeh.server.views.ws] WebSocket connection opened
[2023-12-01 22:26:26,904 |  ERROR | tornado.application] Uncaught exception GET /My_App/ws?theme=dark (172.30.0.8)
HTTPServerRequest(protocol='http', host='foo.bar.dev', method='GET', uri='/My_App/ws?theme=dark', version='HTTP/1.1', remote_ip='172.30.0.8')
Traceback (most recent call last):
  File "/home/pyvenvs/scratch-3.10/lib/python3.10/site-packages/tornado/websocket.py", line 937, in _accept_connection
    open_result = handler.open(*handler.open_args, **handler.open_kwargs)
  File "/home/pyvenvs/scratch-3.10/lib/python3.10/site-packages/tornado/web.py", line 3290, in wrapper
    return method(self, *args, **kwargs)
  File "/home/pyvenvs/scratch-3.10/lib/python3.10/site-packages/bokeh/server/views/ws.py", line 149, in open
    raise ProtocolError("Token is expired.")
bokeh.protocol.exceptions.ProtocolError: Token is expired.

Is it possible to catch this error and open a pop up notification like pn.config.disconnect_notification with a link to reload the page? Is this related to command line setting session-token-expiration?

If markdown works, you can do something like disconnect_notification below, but I haven’t tested.

import panel as pn

pn.extension(
    disconnect_notification='Connection lost, [Click here to reload page](https://localhost:5006)!',
    ready_notification='Application fully loaded.',
    template='bootstrap'
)

slider = pn.widgets.IntSlider(name='Number', start=1, end=10, value=7)

pn.Column(
    slider,
    pn.bind(lambda n: '⭐' * n, slider)
).servable(title='Connection Notifications')

Thanks for the suggestion but I already do that; I should have been more explicit in my question. I actually do this:

pn.config.disconnect_notification = """
    Server Connected Closed <br /> 
    <button class="btn btn-outline-light" onclick="location.reload();">Click To Reconnect</button>
"""
pn.config.ready_notification = "Application fully loaded."

which I borrowed from this post.

The problem is that when a Token expires it doesn’t present itself as websocket disconnection event and the notification doesn’t pop up (as hopefully is evident from my earlier screenshot; although admittedly the bottom is chopped off there).

1 Like

Hi @bsdz

I believe this is not currently supported. Please consider making a feature request.

Thanks.

I’ll try and put a feature request together soon. It looks like it might require a change in Bokeh rather than Panel although I’m not entirely sure. Thanks for the suggestion.

1 Like

It looks like there is an existing feature request in Bokeh for this issue.

# [FEATURE] Improved error message on token expiry

I’ve also traced the parameter “–session-token-expiration” and it seems to originate from Bokeh. From the code there, I’ve gleaned that it defaults to 300 seconds (DEFAULT_SESSION_TOKEN_EXPIRATION). I’ll try and increase this too.

1 Like

Did increasing that value work for you? I am looking for ways to keep my app from timing out and needing to refresh, because I may lose all of the data that I had loaded in when I refresh the page. Thanks.

I’ve not been actively using my Panel recently but IIRC it didn’t help.