Fix "World is not set yet" hiding the original exception during setup
Related: #333
Previously, when an exception occurred during world setup, it was not obvious why because the error message displayed was "World is not set yet." and the true exception was only visible in the logs. That's because another exception during on_unmount overrode it.
Now instead:
Traceback (most recent call last):
File "/home/mzebrak/.pyenv/versions/3.10.13/envs/clive-3.10.13/bin/clive", line 6, in <module>
sys.exit(main())
File "/home/mzebrak/1workspace/clive/clive/main.py", line 23, in main
run_tui()
File "/home/mzebrak/1workspace/clive/clive/__private/run_tui.py", line 19, in run_tui
Clive().run()
File "/home/mzebrak/.pyenv/versions/3.10.13/envs/clive-3.10.13/lib/python3.10/site-packages/textual/app.py", line 1946, in run
asyncio.run(run_app())
File "/home/mzebrak/.pyenv/versions/3.10.13/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/home/mzebrak/.pyenv/versions/3.10.13/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
return future.result()
File "/home/mzebrak/.pyenv/versions/3.10.13/envs/clive-3.10.13/lib/python3.10/site-packages/textual/app.py", line 1932, in run_app
await self.run_async(
File "/home/mzebrak/.pyenv/versions/3.10.13/envs/clive-3.10.13/lib/python3.10/site-packages/textual/app.py", line 1895, in run_async
await asyncio.shield(app._shutdown())
File "/home/mzebrak/.pyenv/versions/3.10.13/envs/clive-3.10.13/lib/python3.10/site-packages/textual/app.py", line 3235, in _shutdown
await self._dispatch_message(events.Unmount())
File "/home/mzebrak/.pyenv/versions/3.10.13/envs/clive-3.10.13/lib/python3.10/site-packages/textual/message_pump.py", line 670, in _dispatch_message
await self.on_event(message)
File "/home/mzebrak/.pyenv/versions/3.10.13/envs/clive-3.10.13/lib/python3.10/site-packages/textual/app.py", line 3571, in on_event
await super().on_event(event)
File "/home/mzebrak/.pyenv/versions/3.10.13/envs/clive-3.10.13/lib/python3.10/site-packages/textual/message_pump.py", line 749, in on_event
await self._on_message(event)
File "/home/mzebrak/.pyenv/versions/3.10.13/envs/clive-3.10.13/lib/python3.10/site-packages/textual/message_pump.py", line 770, in _on_message
await invoke(method, message)
File "/home/mzebrak/.pyenv/versions/3.10.13/envs/clive-3.10.13/lib/python3.10/site-packages/textual/_callback.py", line 93, in invoke
return await _invoke(callback, *params)
File "/home/mzebrak/.pyenv/versions/3.10.13/envs/clive-3.10.13/lib/python3.10/site-packages/textual/_callback.py", line 55, in _invoke
result = await result
File "/home/mzebrak/1workspace/clive/clive/__private/ui/app.py", line 179, in on_unmount
await self.world.close()
File "/home/mzebrak/1workspace/clive/clive/__private/ui/app.py", line 83, in world
assert self._world is not None, "World is not set yet."
AssertionError: World is not set yet.
There will be eg.
< more info>
ClientConnectorError: Cannot connect to host localhost:8193 ssl:default [Connect call failed ('127.0.0.1', 8193)]
The above exception was the direct cause of the following exception:
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ /home/mzebrak/1workspace/clive/clive/__private/ui/app.py:155 in on_load │
│ │
│ 152 │ async def on_load(self) -> None: ╭─────────────────────────────────────── locals ────────────────────────────────────────╮ │
│ 153 │ │ self.console.set_window_title("Clive") │ self = Clive(title='Clive', classes={'-dark-mode'}, pseudo_classes={'focus', 'dark'}) │ │
│ 154 │ │ self._register_quit_signals() ╰───────────────────────────────────────────────────────────────────────────────────────╯ │
│ ❱ 155 │ │ self._world = await TUIWorld().setup() │
│ 156 │ │
│ 157 │ def on_mount(self) -> None: │
│ 158 │ │ self._refresh_node_data_interval = self.set_interval( │
│ │
│ /home/mzebrak/1workspace/clive/clive/__private/core/world.py:138 in setup │
│ │
│ 135 │ │ async with self.during_setup(): ╭───── locals ──────╮ │
│ 136 │ │ │ await self._node.setup() │ self = TUIWorld() │ │
│ 137 │ │ │ if self._use_beekeeper: ╰───────────────────╯ │
│ ❱ 138 │ │ │ │ self._beekeeper = await self.__setup_beekeeper(remote_endpoint=self._bee │
│ 139 │ │ │ │ if self._should_sync_with_beekeeper: │
│ 140 │ │ │ │ │ await self._commands.sync_state_with_beekeeper() │
│ 141 │ │ return self │
│ │
│ /home/mzebrak/1workspace/clive/clive/__private/core/world.py:179 in __setup_beekeeper │
│ │
│ 176 │ │ │ notify_closing_wallet_name_cb=lambda: self.profile.name, ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ 177 │ │ ) │ beekeeper = <clive.__private.core.beekeeper.handle.Beekeeper object at 0x7ffb0d85da50> │ │
│ 178 │ │ beekeeper.attach_wallet_closing_listener(self.app_state) │ remote_endpoint = None │ │
│ ❱ 179 │ │ await beekeeper.launch() │ self = TUIWorld() │ │
│ 180 │ │ return beekeeper ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ 181 │ │
│ 182 │ @property │
│ │
│ /home/mzebrak/1workspace/clive/clive/__private/core/beekeeper/handle.py:142 in launch │
│ │
│ 139 │ │ ) ╭──────────────────────────────────────────────── locals ─────────────────────────────────────────────────╮ │
│ 140 │ │ await self.__start(arguments=arguments) │ arguments = BeekeeperCLIArguments( │ │
│ 141 │ │ if not self._is_session_token_env_var_set(): │ │ help_=False, │ │
│ ❱ 142 │ │ │ await self.__set_token() │ │ version=False, │ │
│ 143 │ │ assert self.token │ │ dump_config=False, │ │
│ 144 │ │ return self │ │ backtrace='yes', │ │
│ 145 │ │ data_dir=PosixPath('/home/mzebrak/.beekeeper'), │ │
│ │ │ export_keys_wallet=None, │ │
│ │ │ log_json_rpc=None, │ │
│ │ │ notifications_endpoint=None, │ │
│ │ │ unlock_timeout=900, │ │
│ │ │ wallet_dir=PosixPath('/home/mzebrak/1workspace/clive'), │ │
│ │ │ webserver_thread_pool_size=32, │ │
│ │ │ webserver_http_endpoint=None │ │
│ │ ) │ │
│ │ backtrace = 'yes' │ │
│ │ data_dir = PosixPath('/home/mzebrak/.beekeeper') │ │
│ │ log_json_rpc = None │ │
│ │ notifications_endpoint = None │ │
│ │ self = <clive.__private.core.beekeeper.handle.Beekeeper object at 0x7ffb0d85da50> │ │
│ │ unlock_timeout = 900 │ │
│ │ wallet_dir = PosixPath('/home/mzebrak/1workspace/clive') │ │
│ │ webserver_http_endpoint = None │ │
│ │ webserver_thread_pool_size = 32 │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/mzebrak/1workspace/clive/clive/__private/core/beekeeper/handle.py:163 in __set_token │
│ │
│ 160 │ ╭───────────────────────────────────── locals ──────────────────────────────────────╮ │
│ 161 │ async def __set_token(self) -> None: │ self = <clive.__private.core.beekeeper.handle.Beekeeper object at 0x7ffb0d85da50> │ │
│ 162 │ │ self.__token = ( ╰───────────────────────────────────────────────────────────────────────────────────╯ │
│ ❱ 163 │ │ │ await self.api.create_session( │
│ 164 │ │ │ │ notifications_endpoint=self.__notification_server.http_endpoint.as_strin │
│ 165 │ │ │ │ salt=str(id(self)), │
│ 166 │ │ │ ) │
│ │
│ /home/mzebrak/1workspace/clive/clive/__private/core/beekeeper/api.py:25 in impl │
│ │
│ 22 │ │ if foo.__name__ not in ["create_session"] and not is_token_already_passed(**kwar ╭────────────────────────────────────── locals ───────────────────────────────────────╮ │
│ 23 │ │ │ kwargs["token"] = this._owner.token │ foo = <function BeekeeperApi.create_session at 0x7ffb0e9afd90> │ │
│ 24 │ │ return ( │ kwargs = {'notifications_endpoint': '127.0.0.1:40963', 'salt': '140716240394832'} │ │
│ ❱ 25 │ │ │ await this._owner._send( │ this = <clive.__private.core.beekeeper.api.BeekeeperApi object at 0x7ffb0d85dc90> │ │
│ 26 │ │ │ │ result_model=get_type_hints(foo)["return"], ╰─────────────────────────────────────────────────────────────────────────────────────╯ │
│ 27 │ │ │ │ endpoint=f"beekeeper_api.{foo.__name__}", │
│ 28 │ │ │ │ **kwargs, │
│ │
│ /home/mzebrak/1workspace/clive/clive/__private/core/beekeeper/handle.py:224 in _send │
│ │
│ 221 │ │ request = JSONRPCRequest(method=endpoint, params=kwargs) │
│ 222 │ │ │
│ 223 │ │ await self.__delay_on_unlock(endpoint) │
│ ❱ 224 │ │ response = await self.__communication.arequest( │
│ 225 │ │ │ url, │
│ 226 │ │ │ data=request.json(by_alias=True), │
│ 227 │ │ │ max_attempts=1, # Beekeeper is not idempotent, so we don't retry e.g. unloc │
│ │
│ ╭────────────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────────────╮ │
│ │ endpoint = 'beekeeper_api.create_session' │ │
│ │ kwargs = {'notifications_endpoint': '127.0.0.1:40963', 'salt': '140716240394832'} │ │
│ │ request = JSONRPCRequest(id_=0, jsonrpc='2.0', method='beekeeper_api.create_session', params={'notifications_endpoint': '127.0.0.1:40963', 'salt': '140716240394832'}) │ │
│ │ result_model = <class 'clive.__private.core.beekeeper.model.CreateSession'> │ │
│ │ self = <clive.__private.core.beekeeper.handle.Beekeeper object at 0x7ffb0d85da50> │ │
│ │ url = 'http://localhost:8193' │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/mzebrak/1workspace/clive/clive/__private/core/communication.py:162 in arequest │
│ │
│ 159 │ │ timeout_total_secs: timeout in seconds (will override the value given during Com ╭────────────────────────────────────────────────── locals ──────────────────────────────────────────────────╮ │
│ 160 │ │ pool_time_secs: time to wait between attempts (will override the value given dur │ data = '{"id": 0, "jsonrpc": "2.0", "method": "beekeeper_api.create_session", "params": '+73 │ │
│ 161 │ │ """ │ max_attempts = 1 │ │
│ ❱ 162 │ │ return await self.__request( │ pool_time_secs = None │ │
│ 163 │ │ │ url, │ self = <clive.__private.core.communication.Communication object at 0x7ffb0d85dab0> │ │
│ 164 │ │ │ data=data, │ timeout_total_secs = None │ │
│ 165 │ │ │ max_attempts=max_attempts, │ url = 'http://localhost:8193' │ │
│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/mzebrak/1workspace/clive/clive/__private/core/communication.py:246 in __request │
│ │
│ 243 │ │ │ │
│ 244 │ │ │ await next_try() │
│ 245 │ │ │
│ ❱ 246 │ │ raise CommunicationError(url, data_serialized, result) from exception │
│ 247 │ │
│ 248 │ @classmethod │
│ 249 │ def __check_response(cls, url: str, request: str, result: Any) -> None: # noqa: ANN │
│ │
│ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ _max_attempts = 1 │ │
│ │ _pool_time_secs = 0.2 │ │
│ │ _timeout_total_secs = 15.0 │ │
│ │ attempt = 1 │ │
│ │ data = '{"id": 0, "jsonrpc": "2.0", "method": "beekeeper_api.create_session", "params": '+73 │ │
│ │ data_serialized = '{"id": 0, "jsonrpc": "2.0", "method": "beekeeper_api.create_session", "params": '+73 │ │
│ │ exception = ClientConnectorError(ConnectionKey(host='localhost', port=8193, is_ssl=False, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None), ConnectionRefusedError(111, "Connect call failed ('127.0.0.1', 8193)")) │ │
│ │ max_attempts = 1 │ │
│ │ next_try = <function Communication.__request.<locals>.next_try at 0x7ffb0d821990> │ │
│ │ pool_time_secs = None │ │
│ │ raise_timeout_error = <function Communication.__request.<locals>.raise_timeout_error at 0x7ffb0d821630> │ │
│ │ result = None │ │
│ │ self = <clive.__private.core.communication.Communication object at 0x7ffb0d85dab0> │ │
│ │ timeout_total_secs = None │ │
│ │ url = 'http://localhost:8193' │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
CommunicationError: Problem occurred during communication with: url=http://localhost:8193, request={"id": 0, "jsonrpc": "2.0", "method": "beekeeper_api.create_session", "params": {"notifications_endpoint": "127.0.0.1:40963", "salt": "140716240394832"}}, no response
available
Edited by Mateusz Żebrak