Recover from an expired session

I finally tried out to recover from an expired session, and it has hugely improved the user experience.

Especially for apps installed on mobile phones, as they go into sleep mode and then the old Timer trick to keep the session alive does not work.

It is simple and safe: the user is logged in again if remember=True, else the app is reloaded and they must log in.

Now the app will not reload as often, so this should be combined with a method to trigger the client side to reload when a new version is available.

import anvil.users
import anvil.server

"""
If the user signed in with remember=True, the session will be reset and the user logged in again after a session timeout.

Be aware that there may be Anvil services that will be impacted by the session reset and that you will have to handle. Please refer to the docs.
"""

def call_s(server_func_name: str, **kwargs):
  return _server_call(anvil.server.call_s, server_func_name, **kwargs)

def call(server_func_name: str, **kwargs):
  return _server_call(anvil.server.call, server_func_name, **kwargs)

def _server_call(server_call_func: callable, server_func_name:str, **kwargs):
  try:
    return server_call_func(server_func_name, **kwargs)
  except anvil.server.SessionExpiredError:
    anvil.server.reset_session()
    if anvil.users.get_user(allow_remembered=True):
      return server_call_func(server_func_name, **kwargs)
    else:
      raise anvil.server.SessionExpiredError()
      
5 Likes

It didn’t work right away, as my variables were passed like this originally:
anvil.server.call('server_function', variable_1, variable_2)

Had to be changed to the following to work:
anvil.server.call('server_function', a=variable_1, b=variable_2)

And then to your method of doing it:
call('server_function', a=variable_1, b=variable_2)

Thank you!

1 Like

Adding positional arguments should fix that: server_func_name, *args, **kwargs

1 Like

You guys have an idea if we can fix the AppOfflineError as well? This is when I open the webapp, set the laptop to sleep, wait a while, wake-up and call your custom call function.

    except (anvil.server.SessionExpiredError, anvil.server.AppOfflineError) as e:
        print('Session expired or app offline, let\'s reset the session')
        anvil.server.reset_session()

This gave me an Offline error on:

anvil.server.reset_session()