From 18f012d2d0b4298e7f8931ef47dd29fc99139f5c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 7 Jun 2024 18:24:25 +0300 Subject: [PATCH] Add better messages for send response errors --- libgm/gmproto/authentication.pb.go | 2 +- libgm/gmproto/client.pb.go | 43 ++++++++++++++++++----------- libgm/gmproto/client.pb.raw | Bin 6215 -> 6318 bytes libgm/gmproto/client.proto | 2 ++ libgm/gmproto/config.pb.go | 2 +- libgm/gmproto/conversations.pb.go | 2 +- libgm/gmproto/events.pb.go | 2 +- libgm/gmproto/pblite.pb.go | 2 +- libgm/gmproto/rpc.pb.go | 5 +++- libgm/gmproto/rpc.pb.raw | Bin 3767 -> 3780 bytes libgm/gmproto/rpc.proto | 1 + libgm/gmproto/settings.pb.go | 2 +- libgm/gmproto/ukey.pb.go | 2 +- libgm/gmproto/util.pb.go | 2 +- messagetracking.go | 3 ++ portal.go | 20 +++++++++++++- 16 files changed, 64 insertions(+), 26 deletions(-) diff --git a/libgm/gmproto/authentication.pb.go b/libgm/gmproto/authentication.pb.go index 50a688a..a5b8454 100644 --- a/libgm/gmproto/authentication.pb.go +++ b/libgm/gmproto/authentication.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: authentication.proto diff --git a/libgm/gmproto/client.pb.go b/libgm/gmproto/client.pb.go index 7849c05..b2bd6f4 100644 --- a/libgm/gmproto/client.pb.go +++ b/libgm/gmproto/client.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: client.proto @@ -2647,7 +2647,8 @@ type SendMessageResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Status SendMessageResponse_Status `protobuf:"varint,3,opt,name=status,proto3,enum=client.SendMessageResponse_Status" json:"status,omitempty"` + GoogleAccountSwitch *AccountChangeOrSomethingEvent `protobuf:"bytes,2,opt,name=googleAccountSwitch,proto3" json:"googleAccountSwitch,omitempty"` + Status SendMessageResponse_Status `protobuf:"varint,3,opt,name=status,proto3,enum=client.SendMessageResponse_Status" json:"status,omitempty"` } func (x *SendMessageResponse) Reset() { @@ -2682,6 +2683,13 @@ func (*SendMessageResponse) Descriptor() ([]byte, []int) { return file_client_proto_rawDescGZIP(), []int{41} } +func (x *SendMessageResponse) GetGoogleAccountSwitch() *AccountChangeOrSomethingEvent { + if x != nil { + return x.GoogleAccountSwitch + } + return nil +} + func (x *SendMessageResponse) GetStatus() SendMessageResponse_Status { if x != nil { return x.Status @@ -3289,7 +3297,8 @@ var file_client_proto_goTypes = []interface{}{ (*SIMPayload)(nil), // 67: settings.SIMPayload (*MessageInfo)(nil), // 68: conversations.MessageInfo (*MessageContent)(nil), // 69: conversations.MessageContent - (*ReactionData)(nil), // 70: conversations.ReactionData + (*AccountChangeOrSomethingEvent)(nil), // 70: events.AccountChangeOrSomethingEvent + (*ReactionData)(nil), // 71: conversations.ReactionData } var file_client_proto_depIdxs = []int32{ 58, // 0: client.ReceiveMessagesRequest.auth:type_name -> authentication.AuthMessage @@ -3329,19 +3338,20 @@ var file_client_proto_depIdxs = []int32{ 46, // 34: client.MessagePayload.messagePayloadContent:type_name -> client.MessagePayloadContent 68, // 35: client.MessagePayload.messageInfo:type_name -> conversations.MessageInfo 69, // 36: client.MessagePayloadContent.messageContent:type_name -> conversations.MessageContent - 4, // 37: client.SendMessageResponse.status:type_name -> client.SendMessageResponse.Status - 70, // 38: client.SendReactionRequest.reactionData:type_name -> conversations.ReactionData - 5, // 39: client.SendReactionRequest.action:type_name -> client.SendReactionRequest.Action - 67, // 40: client.SendReactionRequest.SIMPayload:type_name -> settings.SIMPayload - 57, // 41: client.TypingUpdateRequest.data:type_name -> client.TypingUpdateRequest.Data - 52, // 42: client.ReceiveMessagesRequest.UnknownEmptyObject2.unknown:type_name -> client.ReceiveMessagesRequest.UnknownEmptyObject1 - 60, // 43: client.AckMessageRequest.Message.device:type_name -> authentication.Device - 18, // 44: client.GetThumbnailResponse.Thumbnail.data:type_name -> client.ThumbnailData - 45, // [45:45] is the sub-list for method output_type - 45, // [45:45] is the sub-list for method input_type - 45, // [45:45] is the sub-list for extension type_name - 45, // [45:45] is the sub-list for extension extendee - 0, // [0:45] is the sub-list for field type_name + 70, // 37: client.SendMessageResponse.googleAccountSwitch:type_name -> events.AccountChangeOrSomethingEvent + 4, // 38: client.SendMessageResponse.status:type_name -> client.SendMessageResponse.Status + 71, // 39: client.SendReactionRequest.reactionData:type_name -> conversations.ReactionData + 5, // 40: client.SendReactionRequest.action:type_name -> client.SendReactionRequest.Action + 67, // 41: client.SendReactionRequest.SIMPayload:type_name -> settings.SIMPayload + 57, // 42: client.TypingUpdateRequest.data:type_name -> client.TypingUpdateRequest.Data + 52, // 43: client.ReceiveMessagesRequest.UnknownEmptyObject2.unknown:type_name -> client.ReceiveMessagesRequest.UnknownEmptyObject1 + 60, // 44: client.AckMessageRequest.Message.device:type_name -> authentication.Device + 18, // 45: client.GetThumbnailResponse.Thumbnail.data:type_name -> client.ThumbnailData + 46, // [46:46] is the sub-list for method output_type + 46, // [46:46] is the sub-list for method input_type + 46, // [46:46] is the sub-list for extension type_name + 46, // [46:46] is the sub-list for extension extendee + 0, // [0:46] is the sub-list for field type_name } func init() { file_client_proto_init() } @@ -3353,6 +3363,7 @@ func file_client_proto_init() { file_authentication_proto_init() file_settings_proto_init() file_util_proto_init() + file_events_proto_init() if !protoimpl.UnsafeEnabled { file_client_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*NotifyDittoActivityRequest); i { diff --git a/libgm/gmproto/client.pb.raw b/libgm/gmproto/client.pb.raw index eb5e3a5bd1df9b69e84c230613c4ff6c798c5c0a..01ccd2406ef906b1aac6385be7c42b9da6743051 100644 GIT binary patch delta 152 zcmX?Zu+DHoEQb_NYFTPtN%6+;I+6O{j9kLOsd*{Bsl~;K>8U}f#Rd6!#i>H!T*B%3 z`RO^Sj>*aSrFkX6<(VbP84^qij2hfVs(KI;^q`W?8Hsu6ss2U5`MIej8JT(Mt{@A7 au$dra#l==!l2}q&EWr#kYx8drA7%hRWi@F4 delta 53 zcmZ2yc-&w@?8fX05yeG}T*ASrc`3fB#l?x~sX?j51^Ic!sX|sTQ_v+xRWbFl{mxrRFi`3e|JHs@;q0I}!^ng9R* delta 18 acmX>iyIpp}dQQf+%^Nt|Sth&iH2?re90vga diff --git a/libgm/gmproto/rpc.proto b/libgm/gmproto/rpc.proto index 6abec8f..600845b 100644 --- a/libgm/gmproto/rpc.proto +++ b/libgm/gmproto/rpc.proto @@ -161,6 +161,7 @@ enum ActionType { CREATE_GAIA_PAIRING_CLIENT_FINISHED = 45; UNPAIR_GAIA_PAIRING = 46; CANCEL_GAIA_PAIRING = 47; + PREWARM = 48; } enum MessageType { diff --git a/libgm/gmproto/settings.pb.go b/libgm/gmproto/settings.pb.go index 7a210d6..2e40c37 100644 --- a/libgm/gmproto/settings.pb.go +++ b/libgm/gmproto/settings.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: settings.proto diff --git a/libgm/gmproto/ukey.pb.go b/libgm/gmproto/ukey.pb.go index 5f07c62..eb463b1 100644 --- a/libgm/gmproto/ukey.pb.go +++ b/libgm/gmproto/ukey.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: ukey.proto diff --git a/libgm/gmproto/util.pb.go b/libgm/gmproto/util.pb.go index d0b1c81..52c2de4 100644 --- a/libgm/gmproto/util.pb.go +++ b/libgm/gmproto/util.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: util.proto diff --git a/messagetracking.go b/messagetracking.go index 44fb219..065ee78 100644 --- a/messagetracking.go +++ b/messagetracking.go @@ -86,6 +86,7 @@ func (ose OutgoingStatusError) Is(other error) bool { func errorToStatusReason(err error) (reason event.MessageStatusReason, status event.MessageStatus, isCertain, sendNotice bool, humanMessage string) { var ose OutgoingStatusError + var rse *responseStatusError switch { case errors.Is(err, errUnexpectedParsedContentType), errors.Is(err, errUnknownMsgType): @@ -104,6 +105,8 @@ func errorToStatusReason(err error) (reason event.MessageStatusReason, status ev return event.MessageStatusTooOld, event.MessageStatusRetriable, false, true, "sending the message is taking long; is your phone online?" case errors.Is(err, errTargetNotFound): return event.MessageStatusGenericError, event.MessageStatusFail, true, false, "" + case errors.As(err, &rse): + return event.MessageStatusNetworkError, event.MessageStatusRetriable, true, true, rse.Error() case errors.As(err, &ose): return event.MessageStatusNetworkError, event.MessageStatusFail, true, true, ose.HumanError() default: diff --git a/portal.go b/portal.go index 0dc0258..4873c5d 100644 --- a/portal.go +++ b/portal.go @@ -2049,6 +2049,24 @@ func (portal *Portal) reuploadMedia(ctx context.Context, sender *User, content * return resp, nil } +type responseStatusError gmproto.SendMessageResponse + +func (rse *responseStatusError) Error() string { + switch rse.Status { + case 0: + if rse.GoogleAccountSwitch != nil && strings.ContainsRune(rse.GoogleAccountSwitch.GetAccount(), '@') { + return "Switch back to QR pairing or log in with Google account to send messages" + } + case gmproto.SendMessageResponse_FAILURE_2: + return "Unknown permanent error" + case gmproto.SendMessageResponse_FAILURE_3: + return "Unknown temporary error" + case gmproto.SendMessageResponse_FAILURE_4: + return "Google Messages is not your default SMS app" + } + return fmt.Sprintf("Unrecognized response status %d", rse.Status) +} + func (portal *Portal) HandleMatrixMessage(sender *User, evt *event.Event, timings messageTimings) { ms := metricSender{portal: portal, timings: &timings} @@ -2093,7 +2111,7 @@ func (portal *Portal) HandleMatrixMessage(sender *User, evt *event.Event, timing } else if resp.Status != gmproto.SendMessageResponse_SUCCESS { outgoingMsg.Errored = true outgoingMsg.Acked = true - go ms.sendMessageMetrics(ctx, sender, evt, fmt.Errorf("response status %d", resp.Status), "Error sending", true) + go ms.sendMessageMetrics(ctx, sender, evt, (*responseStatusError)(resp), "Error sending", true) } else { outgoingMsg.Acked = true go ms.sendMessageMetrics(ctx, sender, evt, nil, "", true)