From 1a1fd688124f78cd181245a32cf1d240cc4cc4cb Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 17 Feb 2022 14:09:40 +0200 Subject: [PATCH] Improve connection error handling --- go.mod | 2 +- go.sum | 4 ++-- portal.go | 2 +- puppet.go | 3 +++ user.go | 32 +++++++++++++++++++++++++------- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index bc8271c..07d7fe4 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/prometheus/client_golang v1.11.1 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/tidwall/gjson v1.14.0 - go.mau.fi/whatsmeow v0.0.0-20220215120744-a1550ccceb70 + go.mau.fi/whatsmeow v0.0.0-20220217120518-0bf6c8fb0ce5 golang.org/x/image v0.0.0-20211028202545-6944b10bf410 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd google.golang.org/protobuf v1.27.1 diff --git a/go.sum b/go.sum index 5147fdd..608b2eb 100644 --- a/go.sum +++ b/go.sum @@ -120,8 +120,8 @@ github.com/tidwall/sjson v1.2.4 h1:cuiLzLnaMeBhRmEv00Lpk3tkYrcxpmbU81tAY4Dw0tc= github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910 h1:9FFhG0OmkuMau5UEaTgiUQ+7cSbtbOQ7hiWKdN8OI3I= go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910/go.mod h1:AufGrvVh+00Nc07Jm4hTquh7yleZyn20tKJI2wCPAKg= -go.mau.fi/whatsmeow v0.0.0-20220215120744-a1550ccceb70 h1:6APIMrOUeLr1KZmi9ToqA/mZ6s2fSmpyVdi++hSA9a4= -go.mau.fi/whatsmeow v0.0.0-20220215120744-a1550ccceb70/go.mod h1:NNI4Ah/B27mfQNChJMD1iSO8+HS+fQ4WqNuQ8Mh2/XI= +go.mau.fi/whatsmeow v0.0.0-20220217120518-0bf6c8fb0ce5 h1:hv2cBvttHOiRA/6JUt+yRMAX7CjjER6c+xO2WYqwtA0= +go.mau.fi/whatsmeow v0.0.0-20220217120518-0bf6c8fb0ce5/go.mod h1:NNI4Ah/B27mfQNChJMD1iSO8+HS+fQ4WqNuQ8Mh2/XI= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/portal.go b/portal.go index 7523cb5..9efcbca 100644 --- a/portal.go +++ b/portal.go @@ -2819,7 +2819,7 @@ func (portal *Portal) canBridgeFrom(sender *User, evtType string) bool { if portal.HasRelaybot() { return true } else if sender.Session != nil { - portal.log.Debugln("Ignoring %s from %s as user is not connected", evtType, sender.MXID) + portal.log.Debugfln("Ignoring %s from %s as user is not connected", evtType, sender.MXID) msg := format.RenderMarkdown(fmt.Sprintf("\u26a0 You are not connected to WhatsApp, so your %s was not bridged.", evtType), true, false) msg.MsgType = event.MsgNotice _, err := portal.sendMainIntentMessage(&msg) diff --git a/puppet.go b/puppet.go index 3b0f2c1..6241ada 100644 --- a/puppet.go +++ b/puppet.go @@ -204,6 +204,9 @@ func (puppet *Puppet) UpdateAvatar(source *User) bool { if err != nil { if !errors.Is(err, whatsmeow.ErrProfilePictureUnauthorized) { puppet.log.Warnln("Failed to get avatar URL:", err) + } else if puppet.Avatar == "" { + puppet.Avatar = "unauthorized" + return true } return false } else if avatar == nil { diff --git a/user.go b/user.go index 2678e07..80331cd 100644 --- a/user.go +++ b/user.go @@ -520,7 +520,7 @@ func (user *User) sendPhoneOfflineWarning() { func (user *User) HandleEvent(event interface{}) { switch v := event.(type) { case *events.LoggedOut: - go user.handleLoggedOut(v.OnConnect) + go user.handleLoggedOut(v.OnConnect, v.Reason) user.bridge.Metrics.TrackConnectionState(user.JID, false) user.bridge.Metrics.TrackLoginState(user.JID, false) case *events.Connected: @@ -577,8 +577,22 @@ func (user *User) HandleEvent(event interface{}) { user.JID = v.ID user.addToJIDMap() user.Update() - case *events.ConnectFailure, *events.StreamError: - go user.sendBridgeState(BridgeState{StateEvent: StateUnknownError}) + case *events.StreamError: + var message string + if v.Code != "" { + message = fmt.Sprintf("Unknown stream error with code %s", v.Code) + } else if children := v.Raw.GetChildren(); len(children) > 0 { + message = fmt.Sprintf("Unknown stream error (contains %s node)", children[0].Tag) + } else { + message = "Unknown stream error" + } + go user.sendBridgeState(BridgeState{StateEvent: StateUnknownError, Message: message}) + user.bridge.Metrics.TrackConnectionState(user.JID, false) + case *events.ConnectFailure: + go user.sendBridgeState(BridgeState{StateEvent: StateUnknownError, Message: fmt.Sprintf("Unknown connection failure: %s", v.Reason)}) + user.bridge.Metrics.TrackConnectionState(user.JID, false) + case *events.TemporaryBan: + go user.sendBridgeState(BridgeState{StateEvent: StateBadCredentials, Message: v.String()}) user.bridge.Metrics.TrackConnectionState(user.JID, false) case *events.Disconnected: go user.sendBridgeState(BridgeState{StateEvent: StateTransientDisconnect}) @@ -825,12 +839,12 @@ func (user *User) UpdateDirectChats(chats map[id.UserID][]id.RoomID) { } } -func (user *User) handleLoggedOut(onConnect bool) { - user.sendBridgeState(BridgeState{StateEvent: StateBadCredentials, Error: WALoggedOut}) +func (user *User) handleLoggedOut(onConnect bool, reason events.ConnectFailureReason) { + user.sendBridgeState(BridgeState{StateEvent: StateBadCredentials, Error: WALoggedOut, Message: reason.String()}) user.JID = types.EmptyJID user.Update() if onConnect { - user.sendMarkdownBridgeAlert("Connecting to WhatsApp failed as the device was logged out. Please link the bridge to your phone again.") + user.sendMarkdownBridgeAlert("Connecting to WhatsApp failed as the device was unlinked (error %s). Please link the bridge to your phone again.", reason) } else { user.sendMarkdownBridgeAlert("You were logged out from another device. Please link the bridge to your phone again.") } @@ -867,7 +881,11 @@ func (user *User) ResyncContacts() error { user.log.Infofln("Resyncing displaynames with %d contacts", len(contacts)) for jid, contact := range contacts { puppet := user.bridge.GetPuppetByJID(jid) - puppet.Sync(user, contact) + if puppet != nil { + puppet.Sync(user, contact) + } else { + user.log.Warnfln("Got a nil puppet for %s while syncing contacts", jid) + } } return nil }