This commit is contained in:
2026-10-18 04:32:58 +07:00
parent e85d899fd7
commit c36d3fd314
14 changed files with 446 additions and 50 deletions
+41 -5
View File
@@ -1,3 +1,10 @@
import {
ApiError,
NetworkError,
SessionChangedError,
networkFailure,
type NetworkErrorCode,
} from './request-error.js'
import { createHash } from 'node:crypto'
export interface ScreenPackage {
@@ -30,6 +37,10 @@ export interface PackageRequest {
gameId: number
token: string
signal?: AbortSignal
onRequestFailure?: (failure: {
path: string
reason: NetworkErrorCode | 'SESSION_CHANGED' | 'AUTH' | 'HTTP' | 'INVALID_JSON'
}) => void
}
function object(value: unknown): Record<string, unknown> {
@@ -238,12 +249,35 @@ export async function prepareScreenPackage(
redirect: 'error',
signal,
})
} catch {
throw new Error(
signal.aborted ? 'Подготовка отменена или превышено время ожидания' : 'Сервер недоступен',
)
} catch (error) {
const path = `/api/games/{id}${suffix}`
if (error instanceof ApiError || error instanceof SessionChangedError) {
request.onRequestFailure?.({
path,
reason:
error instanceof ApiError
? [401, 403].includes(error.status)
? 'AUTH'
: 'HTTP'
: 'SESSION_CHANGED',
})
throw error
}
const failure = networkFailure(error, signal)
request.onRequestFailure?.({ path, reason: failure.code })
const name =
suffix === '/music'
? 'Музыка игры'
: suffix === '/screen-plan'
? 'План экранов'
: 'Описание игры'
throw new NetworkError(`${name}: ${failure.message}`, failure.code)
}
if (!response.ok)
if (!response.ok) {
request.onRequestFailure?.({
path: `/api/games/{id}${suffix}`,
reason: [401, 403].includes(response.status) ? 'AUTH' : 'HTTP',
})
throw new Error(
response.status === 401
? 'Требуется авторизация'
@@ -251,9 +285,11 @@ export async function prepareScreenPackage(
? 'Нет доступа к игре'
: `Ошибка API: HTTP ${response.status}`,
)
}
try {
return await response.json()
} catch {
request.onRequestFailure?.({ path: `/api/games/{id}${suffix}`, reason: 'INVALID_JSON' })
throw new Error('Некорректный JSON в ответе API')
}
}