Upload: clearer proxy 413 error, clean up after interrupted uploads

- Show a readable message when a reverse proxy rejects the archive with 413
- Delete the freshly created game if its archive upload fails
- Turn ClientDisconnect during upload into a short 400 instead of a traceback

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mrleo1nidandClaude Opus 5.5 committed 2026-10-25 03:30:43 +03:00
1 parent a97b46079e
commit 5d9ddb6376
3 files changed
+12 -3

No files matched your search

+3 -1
View File
@@ -98,7 +98,9 @@ export function uploadRaw<T>(method: string, url: string, file: Blob,
/* empty */
}
if (xhr.status >= 200 && xhr.status < 300) resolve(data);
else reject(new ApiError(xhr.status, data?.detail ?? xhr.statusText));
else if (xhr.status === 413 && !data?.detail)
reject(new ApiError(413, "Файл слишком большой для прокси перед сервером (client_max_body_size)"));
else reject(new ApiError(xhr.status, data?.detail ?? (xhr.statusText || `Ошибка ${xhr.status}`)));
};
xhr.onerror = () => reject(new ApiError(0, "Сетевая ошибка"));
xhr.send(file);
+4 -1
View File
@@ -16,8 +16,9 @@ export function NewGame() {
if (!file) return;
setError("");
setProgress(0);
let game: Game | null = null;
try {
const game = await api.post<Game>("/api/games", {
game = await api.post<Game>("/api/games", {
title: title.trim() || file.name.replace(/\.(zip|7z|rar|tar.*)$/i, ""),
description,
tags: tags.split(",").map((t) => t.trim()).filter(Boolean),
@@ -26,6 +27,8 @@ export function NewGame() {
file, setProgress);
navigate(`/games/${game.id}`);
} catch (err) {
// don't leave an empty game card behind when the archive never arrived
if (game) await api.del(`/api/games/${game.id}`).catch(() => {});
setError((err as Error).message);
setProgress(null);
}