From 75bf78ad38d818be0cbb61e94b99089f3dea70f7 Mon Sep 17 00:00:00 2001 From: zk Date: Sat, 20 Jun 2026 13:07:10 +0000 Subject: [PATCH] fix: assorted fixes --- .../server/src/lib/orphan-queue/deorphan-bms-pg.ts | 11 +++++++++-- .../framework/score-importing/score-id.ts | 11 ++++++++++- .../framework/score-importing/score-importing.ts | 13 +++++++++++++ typescript/server/src/utils/queries/auth.ts | 2 +- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/typescript/server/src/lib/orphan-queue/deorphan-bms-pg.ts b/typescript/server/src/lib/orphan-queue/deorphan-bms-pg.ts index 9633edc04..8205dab67 100644 --- a/typescript/server/src/lib/orphan-queue/deorphan-bms-pg.ts +++ b/typescript/server/src/lib/orphan-queue/deorphan-bms-pg.ts @@ -10,6 +10,7 @@ import { type ChartDocument, CreateSongID, type GameGroupFromGame, + GameToGameGroup, type SongDocument, } from "tachi-common"; @@ -42,7 +43,13 @@ export async function DeorphanBmsIfInOrphanChartPg( log.info(`Song ${songDoc.title} was unorphaned forcefully (Postgres).`); - const songLegacyId = await GetNextBmsPmsSongLegacyId("bms"); + const gameGroup = GameToGameGroup(game); + + if (gameGroup !== "bms" && gameGroup !== "pms") { + throw new Error(`DeorphanBmsIfInOrphanChartPg called with non-BMS/PMS game: ${game}`); + } + + const songLegacyId = await GetNextBmsPmsSongLegacyId(gameGroup); const songNewID = CreateSongID(); songDoc.id = songNewID; @@ -60,7 +67,7 @@ export async function DeorphanBmsIfInOrphanChartPg( .values({ id: songNewID, legacy_id: songLegacyId, - game_group: "bms", + game_group: gameGroup, title: songDoc.title, artist: songDoc.artist, search_terms: songDoc.searchTerms, diff --git a/typescript/server/src/lib/score-import/framework/score-importing/score-id.ts b/typescript/server/src/lib/score-import/framework/score-importing/score-id.ts index 2dd6ae53a..25f35cd9f 100644 --- a/typescript/server/src/lib/score-import/framework/score-importing/score-id.ts +++ b/typescript/server/src/lib/score-import/framework/score-importing/score-id.ts @@ -11,6 +11,8 @@ import { import type { DryScore } from "../common/types"; +import { InvalidScoreFailure } from "../common/converter-failures"; + export const LEGACY_CHART_ID_LENGTH = 40; export function assertLegacyChartIDForScoreID(legacyChartID: string): void { @@ -46,8 +48,15 @@ export function CreateScoreID( for (const m of Object.keys(gameConfig.providedMetrics)) { const metric = m as keyof MongoProvidedMetrics[V3Game]; + const value = dryScore.scoreData[metric]; - elements[metric] = dryScore.scoreData[metric]; + if (value === undefined) { + throw new InvalidScoreFailure( + `Required metric '${metric}' is undefined in score data for game ${game}. The score may predate this metric being added.`, + ); + } + + elements[metric] = value; } // Also include optional metrics in the checksum if they should be diff --git a/typescript/server/src/lib/score-import/framework/score-importing/score-importing.ts b/typescript/server/src/lib/score-import/framework/score-importing/score-importing.ts index b6e033a18..a3ed7a49d 100644 --- a/typescript/server/src/lib/score-import/framework/score-importing/score-importing.ts +++ b/typescript/server/src/lib/score-import/framework/score-importing/score-importing.ts @@ -153,6 +153,19 @@ export async function ImportIterableDatapoint( // if this isn't a converterFailure, it's just a general error. // Some sort of internal issue? if (!IsConverterFailure(err)) { + // rg-stats ThrowIf assertions produce plain Errors prefixed with + // "Invalid input," - these represent bad user data, not server bugs. + // This is a pretty dirty fix for this, but whatever. + if (err instanceof Error && err.message.startsWith("Invalid input,")) { + log.info({ err }, `rg-stats input assertion failed, treating as InvalidDatapoint.`); + return { + success: false, + type: "InvalidDatapoint", + message: err.message, + content: {}, + }; + } + log.error( { err, diff --git a/typescript/server/src/utils/queries/auth.ts b/typescript/server/src/utils/queries/auth.ts index a2922c2fc..e11eb6762 100644 --- a/typescript/server/src/utils/queries/auth.ts +++ b/typescript/server/src/utils/queries/auth.ts @@ -26,7 +26,7 @@ export async function GetKaiAuthGuaranteed( const authDoc = await GetKaiAuth(userID, service); if (!authDoc) { - log.error(`No authentication was stored for ${service}.`); + log.warn(`No authentication was stored for ${service}.`); throw new ScoreImportFatalError(401, `No authentication was stored for ${service}.`); }