From 1897c1e494342f28bdac914f088f85eeecc23ce8 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Mon, 16 May 2022 00:08:00 -0400 Subject: [PATCH] Try to catch unexpected TalkClient disconnects --- .../kt/client/client.py | 4 ++++ matrix_appservice_kakaotalk/user.py | 16 +++++++++++++++ node/src/client.js | 20 +++++++++++++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/matrix_appservice_kakaotalk/kt/client/client.py b/matrix_appservice_kakaotalk/kt/client/client.py index 7360075..ff4f90f 100644 --- a/matrix_appservice_kakaotalk/kt/client/client.py +++ b/matrix_appservice_kakaotalk/kt/client/client.py @@ -687,6 +687,9 @@ class Client: def _on_error(self, data: dict[str, JSON]) -> Awaitable[None]: return self.user.on_error(data) + def _on_unexpected_disconnect(self, _: dict[str, JSON]) -> Awaitable[None]: + return self.user.on_unexpected_disconnect() + def _start_listen(self) -> None: self._add_event_handler("chat", self._on_chat) @@ -704,6 +707,7 @@ class Client: self._add_event_handler("disconnected", self._on_listen_disconnect) self._add_event_handler("switch_server", self._on_switch_server) self._add_event_handler("error", self._on_error) + self._add_event_handler("unexpected_disconnect", self._on_unexpected_disconnect) def _stop_listen(self) -> None: for method in self._handler_methods: diff --git a/matrix_appservice_kakaotalk/user.py b/matrix_appservice_kakaotalk/user.py index 937aa5a..f06e37c 100644 --- a/matrix_appservice_kakaotalk/user.py +++ b/matrix_appservice_kakaotalk/user.py @@ -770,6 +770,22 @@ class User(DBUser, BaseUser): error_message=str(error), ) + async def on_unexpected_disconnect(self) -> None: + self.is_connected = False + self._track_metric(METRIC_CONNECTED, False) + if self.config["bridge.remain_logged_in_on_disconnect"]: + # TODO What bridge state to push? + self.was_connected = False + await self.save() + reason_suffix = "To reconnect, use the `sync` command." + else: + await self.logout() + reason_suffix = "You are now logged out. To log back in, use the `login` command." + await self.send_bridge_notice( + f"Disconnected from KakaoTalk: unexpected error in backend helper module. {reason_suffix}", + important=True, + ) + async def on_client_disconnect(self) -> None: self.is_connected = False self._track_metric(METRIC_CONNECTED, False) diff --git a/node/src/client.js b/node/src/client.js index 7022f8e..1398fdf 100644 --- a/node/src/client.js +++ b/node/src/client.js @@ -98,6 +98,7 @@ class PermError extends ProtocolError { class UserClient { static #initializing = false + #connected = false #talkClient = new TalkClient() get talkClient() { return this.#talkClient } @@ -390,19 +391,26 @@ class UserClient { if (credential && this.#credential != credential) { await this.setCredential(credential) } - return await this.#talkClient.login(this.#credential) + const res = await this.#talkClient.login(this.#credential) + this.#connected = res.success + return res } disconnect() { - if (this.#talkClient.logon) { + if (this.isConnected()) { this.#talkClient.close() } + this.#connected = false } isConnected() { return this.#talkClient?.logon || false } + isUnexpectedlyDisconnected() { + return this.#connected && !this.isConnected() + } + /** * Send a user-specific command with (optional) data to the socket. * @@ -1321,6 +1329,14 @@ export default class PeerClient { ) } await this.write(resp) + if ("mxid" in req) { + const userClient = this.#tryGetUser(req.mxid) + if (userClient && userClient.isUnexpectedlyDisconnected()) { + this.error("Unexpected disconnect for user", req.mxid) + this.userClients.delete(req.mxid) + await userClient.write("unexpected_disconnect") + } + } } /**