Try to catch unexpected TalkClient disconnects

This commit is contained in:
Andrew Ferrazzutti 2022-05-16 00:08:00 -04:00
parent 2cd7697aa5
commit 1897c1e494
3 changed files with 38 additions and 2 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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")
}
}
}
/**