Эх сурвалжийг харах

Handle startup connection errors

Tulir Asokan 6 жил өмнө
parent
commit
e25bf29609
3 өөрчлөгдсөн 46 нэмэгдсэн , 19 устгасан
  1. 33 14
      commands.go
  2. 3 0
      example-config.yaml
  3. 10 5
      user.go

+ 33 - 14
commands.go

@@ -81,18 +81,20 @@ func (handler *CommandHandler) Handle(roomID types.MatrixRoomID, user *User, mes
 		handler.CommandLogin(ce)
 	case "help":
 		handler.CommandHelp(ce)
-	case "logout", "reconnect", "disconnect", "sync", "list", "open", "pm":
+	case "reconnect":
+		handler.CommandReconnect(ce)
+	case "logout", "disconnect", "sync", "list", "open", "pm":
 		if ce.User.Conn == nil {
-			ce.Reply("You are not logged in.")
-			ce.Reply("Please use the login command to log into WhatsApp.")
+			ce.Reply("You are not logged in. Use the `login` command to log into WhatsApp.")
+			return
+		} else if !ce.User.Connected {
+			ce.Reply("You are not connected to WhatsApp. Use the `reconnect` command to reconnect.")
 			return
 		}
 
 		switch cmd {
 		case "logout":
 			handler.CommandLogout(ce)
-		case "reconnect":
-			handler.CommandReconnect(ce)
 		case "disconnect":
 			handler.CommandDisconnect(ce)
 		case "sync":
@@ -130,7 +132,7 @@ func (handler *CommandHandler) CommandLogout(ce *CommandEvent) {
 	err := ce.User.Conn.Logout()
 	if err != nil {
 		ce.User.log.Warnln("Error while logging out:", err)
-		ce.Reply("Error while logging out (see logs for details)")
+		ce.Reply("Unknown error while logging out: %v", err)
 		return
 	}
 	_, err = ce.User.Conn.Disconnect()
@@ -148,16 +150,33 @@ const cmdReconnectHelp = `reconnect - Reconnect to WhatsApp`
 
 func (handler *CommandHandler) CommandReconnect(ce *CommandEvent) {
 	err := ce.User.Conn.Restore()
-	if err == whatsapp.ErrAlreadyLoggedIn {
-		if ce.User.Connected {
-			ce.Reply("You were already connected.")
+	if err == whatsapp.ErrInvalidSession {
+		if ce.User.Session != nil {
+			ce.User.log.Debugln("Got invalid session error when reconnecting, but user has session. Retrying using RestoreWithSession()...")
+			var sess whatsapp.Session
+			sess, err = ce.User.Conn.RestoreWithSession(*ce.User.Session)
+			if err == nil {
+				ce.User.SetSession(&sess)
+			}
 		} else {
-			ce.User.Connected = true
-			ce.Reply("You were already connected, but the bridge hadn't noticed. Fixed that now.")
+			ce.Reply("You are not logged in.")
+			return
 		}
-	} else if err != nil {
+	}
+	if err != nil {
 		ce.User.log.Warnln("Error while reconnecting:", err)
-		ce.Reply("Error while reconnecting (see logs for details)")
+		if err == whatsapp.ErrAlreadyLoggedIn {
+			if ce.User.Connected {
+				ce.Reply("You were already connected.")
+			} else {
+				ce.User.Connected = true
+				ce.Reply("You were already connected, but the bridge hadn't noticed. Fixed that now.")
+			}
+		} else if err.Error() == "restore session connection timed out" {
+			ce.Reply("Reconnection timed out. Is WhatsApp on your phone reachable?")
+		} else {
+			ce.Reply("Unknown error while reconnecting: %v", err)
+		}
 		return
 	}
 	ce.User.Connected = true
@@ -174,7 +193,7 @@ func (handler *CommandHandler) CommandDisconnect(ce *CommandEvent) {
 		return
 	} else if err != nil {
 		ce.User.log.Warnln("Error while disconnecting:", err)
-		ce.Reply("Error while disconnecting (see logs for details)")
+		ce.Reply("Unknown error while disconnecting: %v", err)
 		return
 	}
 	ce.User.SetSession(&sess)

+ 3 - 0
example-config.yaml

@@ -54,6 +54,9 @@ bridge:
     # {{.Short}}  - short display name from contact list
     displayname_template: "{{if .Notify}}{{.Notify}}{{else}}{{.Jid}}{{end}} (WA)"
 
+    # WhatsApp connection timeout in seconds.
+    connection_timeout: 20
+
     # The prefix for commands. Only required in non-management rooms.
     command_prefix: "!wa"
 

+ 10 - 5
user.go

@@ -162,6 +162,10 @@ func (user *User) RestoreSession() bool {
 		sess, err := user.Conn.RestoreWithSession(*user.Session)
 		if err != nil {
 			user.log.Errorln("Failed to restore session:", err)
+			msg := format.RenderMarkdown(fmt.Sprintf("\u26a0 Failed to connect to WhatsApp. Make sure WhatsApp "+
+				"on your phone is reachable and use `%s reconnect` to try connecting again.",
+				user.bridge.Config.Bridge.CommandPrefix))
+			_, _ = user.bridge.Bot.SendMessageEvent(user.ManagementRoom, mautrix.EventMessage, msg)
 			return false
 		}
 		user.Connected = true
@@ -186,7 +190,7 @@ func (user *User) Login(ce *CommandEvent) {
 		qrCode, err := qrcode.Encode(code, qrcode.Low, 256)
 		if err != nil {
 			user.log.Errorln("Failed to encode QR code:", err)
-			ce.Reply("Failed to encode QR code (see logs for details)")
+			ce.Reply("Failed to encode QR code: %v", err)
 			return
 		}
 
@@ -195,7 +199,7 @@ func (user *User) Login(ce *CommandEvent) {
 		resp, err := bot.UploadBytes(qrCode, "image/png")
 		if err != nil {
 			user.log.Errorln("Failed to upload QR code:", err)
-			ce.Reply("Failed to upload QR code (see logs for details)")
+			ce.Reply("Failed to upload QR code: %v", err)
 			return
 		}
 
@@ -211,16 +215,17 @@ func (user *User) Login(ce *CommandEvent) {
 			ce.Reply("You're already logged in.")
 		} else if err == whatsapp.ErrLoginInProgress {
 			ce.Reply("You have a login in progress already.")
+		} else if err.Error() == "qr code scan timed out" {
+			ce.Reply("QR code scan timed out. Please try again.")
 		} else {
 			user.log.Warnln("Failed to log in:", err)
-			ce.Reply("Failed to log in (see logs for details)")
+			ce.Reply("Failed to log in: %v", err)
 		}
 		return
 	}
 	user.Connected = true
 	user.JID = strings.Replace(user.Conn.Info.Wid, whatsappExt.OldUserSuffix, whatsappExt.NewUserSuffix, 1)
-	user.Session = &session
-	user.Update()
+	user.SetSession(&session)
 	ce.Reply("Successfully logged in. Now, you may ask for `sync [--create]`.")
 }