fix: acknowledge unsupported broadcast member removal

This commit is contained in:
zhx 2026-07-10 11:59:24 +08:00
parent 5338861674
commit dde07b734a
2 changed files with 31 additions and 1 deletions

View File

@ -222,6 +222,13 @@ func (s *Service) RemoveRegionBroadcastMember(ctx context.Context, userID int64,
return "", false, xerr.New(xerr.InvalidArgument, err.Error())
}
if err := s.publisher.DeleteGroupMember(ctx, groupID, userID); err != nil {
var restErr tencentim.RESTError
if errors.As(err, &restErr) && restErr.Code == 10007 && strings.Contains(strings.ToLower(restErr.Info), "disable kick member") {
// 区域播报群是 AVChatRoom腾讯 IM 明确不允许服务端踢成员。用户换区依靠客户端
// 离开旧群并加入新群;这个永久能力拒绝不能重试,否则每条 UserRegionChanged
// 都会重投到 DLQ。removed=false 保留真实结果nil 让 MQ 确认该读模型操作已降级完成。
return groupID, false, nil
}
return groupID, false, err
}
// 过渡期老客户端可能仍在 v1 旧区域群里,切区时一并尽力移除;

View File

@ -333,6 +333,28 @@ func TestRemoveRegionBroadcastMemberDeletesOnlyUserMembership(t *testing.T) {
}
}
func TestRemoveRegionBroadcastMemberAcknowledgesAVChatKickRestriction(t *testing.T) {
publisher := &fakePublisher{deleteError: tencentim.RESTError{Code: 10007, Info: "this group disable kick member"}}
service := New(Config{NodeID: "node-a"}, newFakeRepository(), publisher, nil)
groupID, removed, err := service.RemoveRegionBroadcastMember(appcode.WithContext(context.Background(), "lalu"), 42, 1001)
if err != nil {
t.Fatalf("AVChat kick restriction must be acknowledged without retry: %v", err)
}
if removed || groupID != "hy_lalu_bc_r_v2_1001" {
t.Fatalf("AVChat restriction result mismatch: group_id=%s removed=%t", groupID, removed)
}
if len(publisher.deletedGroupIDs) != 1 {
t.Fatalf("unsupported v2 removal must not retry the legacy AVChat group: %v", publisher.deletedGroupIDs)
}
// 10007 还可能表示其他群业务错误;只能降级腾讯明确返回的 disable-kick 语义。
publisher.deleteError = tencentim.RESTError{Code: 10007, Info: "another group error"}
if _, _, err := service.RemoveRegionBroadcastMember(appcode.WithContext(context.Background(), "lalu"), 42, 1001); err == nil {
t.Fatal("unrelated Tencent IM 10007 error must remain retryable")
}
}
func TestRegionBroadcastUsesConfiguredGroupPrefix(t *testing.T) {
repository := newFakeRepository()
publisher := &fakePublisher{}
@ -520,6 +542,7 @@ type fakePublisher struct {
ensureErrors map[string]error
deletedGroupIDs []string
deletedUserID int64
deleteError error
}
func (p *fakePublisher) EnsureGroup(_ context.Context, spec tencentim.GroupSpec) error {
@ -535,7 +558,7 @@ func (p *fakePublisher) PublishGroupCustomMessage(_ context.Context, message ten
func (p *fakePublisher) DeleteGroupMember(_ context.Context, groupID string, userID int64) error {
p.deletedGroupIDs = append(p.deletedGroupIDs, groupID)
p.deletedUserID = userID
return nil
return p.deleteError
}
type fakeRegionSource struct {