mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-13 06:36:49 -05:00
Handle race when two groups match up with same target
GroupMatch has unique constraints on both alphaGroupId and bravoGroupId (a group can only be in one match). If two managers click MATCH_UP at nearly the same moment against overlapping groups, the second INSERT trips SQLITE_CONSTRAINT_UNIQUE and bubbles up as a 500. Translate that error into a SendouQError inside SQMatchRepository.create so the q/looking action's existing SendouQError catch treats it like any other stale-state error and returns null, which causes the loader to re-run and the user sees the fresh state instead of an error page.
This commit is contained in:
@@ -16,8 +16,10 @@ import {
|
||||
concatUserSubmittedImagePrefix,
|
||||
tournamentLogoWithDefault,
|
||||
} from "~/utils/kysely.server";
|
||||
import { errorIsSqliteUniqueConstraintFailure } from "~/utils/sql";
|
||||
import type { Unpacked } from "~/utils/types";
|
||||
import { FULL_GROUP_SIZE } from "../sendouq/q-constants";
|
||||
import { SendouQError } from "../sendouq/q-utils.server";
|
||||
import * as SQGroupRepository from "../sendouq/SQGroupRepository.server";
|
||||
import { MATCHES_PER_SEASONS_PAGE } from "../user-page/user-page-constants";
|
||||
import { compareMatchToReportedScores } from "./core/match.server";
|
||||
@@ -410,7 +412,15 @@ export function create({
|
||||
memento: JSON.stringify(memento),
|
||||
})
|
||||
.returningAll()
|
||||
.executeTakeFirstOrThrow();
|
||||
.executeTakeFirstOrThrow()
|
||||
.catch((error) => {
|
||||
// race: another manager matched one of the two groups first, tripping the
|
||||
// unique constraint on GroupMatch.alphaGroupId / bravoGroupId
|
||||
if (errorIsSqliteUniqueConstraintFailure(error)) {
|
||||
throw new SendouQError("Group is already in a match");
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
|
||||
await trx
|
||||
.insertInto("GroupMatchMap")
|
||||
|
||||
Reference in New Issue
Block a user