Tournament match id / team id resolution that doesn't cause HTTP 500 response

This commit is contained in:
Kalle
2024-07-27 00:01:29 +03:00
parent 8afbe29086
commit d5c4d84e2e
6 changed files with 38 additions and 31 deletions

View File

@@ -3,16 +3,18 @@ import { eventStream } from "remix-utils/sse/server";
import { getUserId } from "~/features/auth/core/user.server";
import { ignoreTransaction } from "~/utils/newrelic.server";
import { parseParams } from "~/utils/remix";
import { emitter } from "../core/emitters.server";
import {
matchIdFromParams,
matchSubscriptionKey,
} from "../tournament-bracket-utils";
import { matchPageParamsSchema } from "../tournament-bracket-schemas.server";
import { matchSubscriptionKey } from "../tournament-bracket-utils";
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
ignoreTransaction();
const loggedInUser = await getUserId(request);
const matchId = matchIdFromParams(params);
const matchId = parseParams({
params,
schema: matchPageParamsSchema,
}).mid;
return eventStream(request.signal, (send) => {
const handler = (args: { eventId: string; userId: number }) => {

View File

@@ -18,7 +18,12 @@ import { useVisibilityChange } from "~/hooks/useVisibilityChange";
import { canReportTournamentScore } from "~/permissions";
import invariant from "~/utils/invariant";
import { logger } from "~/utils/logger";
import { notFoundIfFalsy, parseRequestPayload, validate } from "~/utils/remix";
import {
notFoundIfFalsy,
parseParams,
parseRequestPayload,
validate,
} from "~/utils/remix";
import { assertUnreachable } from "~/utils/types";
import {
tournamentBracketsPage,
@@ -46,12 +51,14 @@ import { findResultsByMatchId } from "../queries/findResultsByMatchId.server";
import { insertTournamentMatchGameResult } from "../queries/insertTournamentMatchGameResult.server";
import { insertTournamentMatchGameResultParticipant } from "../queries/insertTournamentMatchGameResultParticipant.server";
import { updateMatchGameResultPoints } from "../queries/updateMatchGameResultPoints.server";
import { matchSchema } from "../tournament-bracket-schemas.server";
import {
matchPageParamsSchema,
matchSchema,
} from "../tournament-bracket-schemas.server";
import {
bracketSubscriptionKey,
groupNumberToLetter,
isSetOverByScore,
matchIdFromParams,
matchIsLocked,
matchSubscriptionKey,
tournamentTeamToActiveRosterUserIds,
@@ -61,7 +68,10 @@ import "../tournament-bracket.css";
export const action: ActionFunction = async ({ params, request }) => {
const user = await requireUser(request);
const matchId = matchIdFromParams(params);
const matchId = parseParams({
params,
schema: matchPageParamsSchema,
}).mid;
const match = notFoundIfFalsy(findMatchById(matchId));
const data = await parseRequestPayload({
request,
@@ -535,7 +545,10 @@ export type TournamentMatchLoaderData = typeof loader;
export const loader = async ({ params }: LoaderFunctionArgs) => {
const tournamentId = tournamentIdFromParams(params);
const matchId = matchIdFromParams(params);
const matchId = parseParams({
params,
schema: matchPageParamsSchema,
}).mid;
const match = notFoundIfFalsy(findMatchById(matchId));

View File

@@ -133,3 +133,9 @@ export const bracketSchema = z.union([
bracketIdx,
}),
]);
export const matchPageParamsSchema = z.object({ mid: z.coerce.number() });
export const tournamentTeamPageParamsSchema = z.object({
tid: z.coerce.number(),
});

View File

@@ -1,4 +1,3 @@
import type { Params } from "@remix-run/react";
import type { TFunction } from "i18next";
import type { TournamentRoundMaps } from "~/db/tables";
import type { TournamentMatch } from "~/db/types";
@@ -10,20 +9,12 @@ import {
sourceTypes,
} from "~/modules/tournament-map-list-generator";
import { removeDuplicates } from "~/utils/arrays";
import invariant from "~/utils/invariant";
import { sumArray } from "~/utils/number";
import type { FindMatchById } from "../tournament-bracket/queries/findMatchById.server";
import type { TournamentLoaderData } from "../tournament/routes/to.$id";
import type { Tournament } from "./core/Tournament";
import type { TournamentDataTeam } from "./core/Tournament.server";
export function matchIdFromParams(params: Params<string>) {
const result = Number(params.mid);
invariant(!Number.isNaN(result), "mid is not a number");
return result;
}
const NUM_MAP = {
"1": ["1", "2", "4"],
"2": ["2", "1", "3", "5"],

View File

@@ -8,7 +8,9 @@ import { Placement } from "~/components/Placement";
import { Popover } from "~/components/Popover";
import { Redirect } from "~/components/Redirect";
import type { TournamentDataTeam } from "~/features/tournament-bracket/core/Tournament.server";
import { tournamentTeamPageParamsSchema } from "~/features/tournament-bracket/tournament-bracket-schemas.server";
import type { TournamentMaplistSource } from "~/modules/tournament-map-list-generator";
import { parseParams } from "~/utils/remix";
import {
teamPage,
tournamentMatchPage,
@@ -22,15 +24,15 @@ import {
tournamentTeamSets,
winCounts,
} from "../core/sets.server";
import {
tournamentIdFromParams,
tournamentTeamIdFromParams,
} from "../tournament-utils";
import { tournamentIdFromParams } from "../tournament-utils";
import { useTournament } from "./to.$id";
export const loader = ({ params }: LoaderFunctionArgs) => {
const tournamentId = tournamentIdFromParams(params);
const tournamentTeamId = tournamentTeamIdFromParams(params);
const tournamentTeamId = parseParams({
params,
schema: tournamentTeamPageParamsSchema,
}).tid;
const sets = tournamentTeamSets({ tournamentTeamId, tournamentId });

View File

@@ -17,13 +17,6 @@ export function tournamentIdFromParams(params: Params<string>) {
return result;
}
export function tournamentTeamIdFromParams(params: Params<string>) {
const result = Number(params.tid);
invariant(!Number.isNaN(result), "tid is not a number");
return result;
}
export function modesIncluded(
tournament: Pick<Tournament, "mapPickingStyle">,
): ModeShort[] {