Selaa lähdekoodia

Improve connection error handling

Tulir Asokan 3 vuotta sitten
vanhempi
sitoutus
1a1fd68812
5 muutettua tiedostoa jossa 32 lisäystä ja 11 poistoa
  1. 1 1
      go.mod
  2. 2 2
      go.sum
  3. 1 1
      portal.go
  4. 3 0
      puppet.go
  5. 25 7
      user.go

+ 1 - 1
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

+ 2 - 2
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=

+ 1 - 1
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)

+ 3 - 0
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 {

+ 25 - 7
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
 }