@@ -127,7 +127,11 @@ func (s AGPLIDPSync) SyncOrganizations(ctx context.Context, tx database.Store, u
127
127
// Find the difference in the expected and the existing orgs, and
128
128
// correct the set of orgs the user is a member of.
129
129
add , remove := slice .SymmetricDifference (existingOrgIDs , finalExpected )
130
- notExists := make ([]uuid.UUID , 0 )
130
+ // notExists is purely for debugging. It logs when the settings want
131
+ // a user in an organization, but the organization does not exist.
132
+ notExists := slice .DifferenceFunc (expectedOrgIDs , finalExpected , func (a , b uuid.UUID ) bool {
133
+ return a == b
134
+ })
131
135
for _ , orgID := range add {
132
136
_ , err := tx .InsertOrganizationMember (ctx , database.InsertOrganizationMemberParams {
133
137
OrganizationID : orgID ,
@@ -138,9 +142,26 @@ func (s AGPLIDPSync) SyncOrganizations(ctx context.Context, tx database.Store, u
138
142
})
139
143
if err != nil {
140
144
if xerrors .Is (err , sql .ErrNoRows ) {
145
+ // This should not happen because we check the org existance
146
+ // beforehand.
141
147
notExists = append (notExists , orgID )
142
148
continue
143
149
}
150
+
151
+ if database .IsUniqueViolation (err , database .UniqueOrganizationMembersPkey ) {
152
+ // If we hit this error we have a bug. The user already exists in the
153
+ // organization, but was not detected to be at the start of this function.
154
+ // Instead of failing the function, an error will be logged. This is to not bring
155
+ // down the entire syncing behavior from a single failed org. Failing this can
156
+ // prevent user logins, so only fatal non-recoverable errors should be returned.
157
+ s .Logger .Error (ctx , "syncing user to organization failed as they are already a member, please report this failure to Coder" ,
158
+ slog .F ("user_id" , user .ID ),
159
+ slog .F ("username" , user .Username ),
160
+ slog .F ("organization_id" , orgID ),
161
+ slog .Error (err ),
162
+ )
163
+ continue
164
+ }
144
165
return xerrors .Errorf ("add user to organization: %w" , err )
145
166
}
146
167
}
@@ -156,6 +177,7 @@ func (s AGPLIDPSync) SyncOrganizations(ctx context.Context, tx database.Store, u
156
177
}
157
178
158
179
if len (notExists ) > 0 {
180
+ notExists = slice .Unique (notExists ) // Remove dupes
159
181
s .Logger .Debug (ctx , "organizations do not exist but attempted to use in org sync" ,
160
182
slog .F ("not_found" , notExists ),
161
183
slog .F ("user_id" , user .ID ),
0 commit comments