fix(invites): distinguish CAS contention from a real use-cap (retry vs reject)
claimInviteUse returned null both when the cap was truly reached and when it lost the compare-and-swap 5× under load, so a legitimate joiner on a busy high-cap invite got a false 'invite has reached its use cap'. Return a discriminated result; map contention to a distinct 'try again' message. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
33b2475e67
commit
61ffc2e01f
+10
-2
@@ -182,8 +182,16 @@ export async function joinSpace(formData: {
|
||||
// (The pre-check above is a fast UX reject; this is the authoritative guard.)
|
||||
let claimedCount: number | null = null
|
||||
if (invite) {
|
||||
claimedCount = await claimInviteUse(admin, invite.id, invite.uses_count, invite.max_uses)
|
||||
if (claimedCount === null) return { error: 'This invite has reached its use cap.' }
|
||||
const claim = await claimInviteUse(admin, invite.id, invite.uses_count, invite.max_uses)
|
||||
if (!claim.ok) {
|
||||
return {
|
||||
error:
|
||||
claim.reason === 'contention'
|
||||
? 'Too many people are joining at once — please try again.'
|
||||
: 'This invite has reached its use cap.',
|
||||
}
|
||||
}
|
||||
claimedCount = claim.count
|
||||
}
|
||||
|
||||
const { data: newMember, error: memberErr } = await admin
|
||||
|
||||
Reference in New Issue
Block a user