Fix GUI failed response handling
This commit is contained in:
parent
f5bc53c92c
commit
334dcd1edf
3 changed files with 33 additions and 10 deletions
|
|
@ -1122,7 +1122,7 @@ function endPan(pointerId: number | null = null): void {
|
|||
async function loadRuntimeConfig(): Promise<void> {
|
||||
const response = await fetch("/api/config");
|
||||
if (!response.ok) {
|
||||
throw new Error(await response.text());
|
||||
throw new Error(await responseErrorMessage(response, "Failed to load runtime config."));
|
||||
}
|
||||
applyRuntimeConfig((await response.json()) as RuntimeConfig);
|
||||
}
|
||||
|
|
@ -1138,7 +1138,7 @@ async function refreshQueueSummary(): Promise<void> {
|
|||
}
|
||||
const response = await fetch("/api/queue");
|
||||
if (!response.ok) {
|
||||
throw new Error(await response.text());
|
||||
throw new Error(await responseErrorMessage(response, "Failed to load queue summary."));
|
||||
}
|
||||
state.queueSummary = (await response.json()) as QueueSummary;
|
||||
renderQueueSummary();
|
||||
|
|
@ -1223,6 +1223,18 @@ function extractErrorDetail(payload: unknown, fallback: string): string {
|
|||
return fallback;
|
||||
}
|
||||
|
||||
async function responseErrorMessage(response: Response, fallback: string): Promise<string> {
|
||||
const body = await response.text();
|
||||
if (!body.trim()) {
|
||||
return fallback;
|
||||
}
|
||||
try {
|
||||
return extractErrorDetail(JSON.parse(body), fallback);
|
||||
} catch {
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
||||
async function cancelCurrentJob(options: { keepalive?: boolean; silent?: boolean } = {}): Promise<void> {
|
||||
if (!state.jobId || !hasActiveJob()) {
|
||||
return;
|
||||
|
|
@ -1237,7 +1249,7 @@ async function cancelCurrentJob(options: { keepalive?: boolean; silent?: boolean
|
|||
try {
|
||||
const response = await request;
|
||||
if (!response.ok) {
|
||||
throw new Error(await response.text());
|
||||
throw new Error(await responseErrorMessage(response, "Failed to cancel the current job."));
|
||||
}
|
||||
const payload = (await response.json()) as JobStateSnapshot;
|
||||
applyJobSnapshot(payload);
|
||||
|
|
@ -1573,8 +1585,7 @@ async function startRun(): Promise<void> {
|
|||
body: buildFormData(),
|
||||
});
|
||||
if (!response.ok) {
|
||||
const errorPayload = await response.json().catch(async () => ({ detail: await response.text() }));
|
||||
throw new Error(extractErrorDetail(errorPayload, "Failed to start GUI job."));
|
||||
throw new Error(await responseErrorMessage(response, "Failed to start GUI job."));
|
||||
}
|
||||
const payload = (await response.json()) as JobStateSnapshot;
|
||||
state.jobId = payload.jobId;
|
||||
|
|
|
|||
|
|
@ -887,7 +887,7 @@ function endPan(pointerId = null) {
|
|||
async function loadRuntimeConfig() {
|
||||
const response = await fetch("/api/config");
|
||||
if (!response.ok) {
|
||||
throw new Error(await response.text());
|
||||
throw new Error(await responseErrorMessage(response, "Failed to load runtime config."));
|
||||
}
|
||||
applyRuntimeConfig((await response.json()));
|
||||
}
|
||||
|
|
@ -902,7 +902,7 @@ async function refreshQueueSummary() {
|
|||
}
|
||||
const response = await fetch("/api/queue");
|
||||
if (!response.ok) {
|
||||
throw new Error(await response.text());
|
||||
throw new Error(await responseErrorMessage(response, "Failed to load queue summary."));
|
||||
}
|
||||
state.queueSummary = (await response.json());
|
||||
renderQueueSummary();
|
||||
|
|
@ -979,6 +979,18 @@ function extractErrorDetail(payload, fallback) {
|
|||
}
|
||||
return fallback;
|
||||
}
|
||||
async function responseErrorMessage(response, fallback) {
|
||||
const body = await response.text();
|
||||
if (!body.trim()) {
|
||||
return fallback;
|
||||
}
|
||||
try {
|
||||
return extractErrorDetail(JSON.parse(body), fallback);
|
||||
}
|
||||
catch {
|
||||
return body;
|
||||
}
|
||||
}
|
||||
async function cancelCurrentJob(options = {}) {
|
||||
if (!state.jobId || !hasActiveJob()) {
|
||||
return;
|
||||
|
|
@ -993,7 +1005,7 @@ async function cancelCurrentJob(options = {}) {
|
|||
try {
|
||||
const response = await request;
|
||||
if (!response.ok) {
|
||||
throw new Error(await response.text());
|
||||
throw new Error(await responseErrorMessage(response, "Failed to cancel the current job."));
|
||||
}
|
||||
const payload = (await response.json());
|
||||
applyJobSnapshot(payload);
|
||||
|
|
@ -1287,8 +1299,7 @@ async function startRun() {
|
|||
body: buildFormData(),
|
||||
});
|
||||
if (!response.ok) {
|
||||
const errorPayload = await response.json().catch(async () => ({ detail: await response.text() }));
|
||||
throw new Error(extractErrorDetail(errorPayload, "Failed to start GUI job."));
|
||||
throw new Error(await responseErrorMessage(response, "Failed to start GUI job."));
|
||||
}
|
||||
const payload = (await response.json());
|
||||
state.jobId = payload.jobId;
|
||||
|
|
|
|||
|
|
@ -25,3 +25,4 @@
|
|||
{"ts": "2026-04-29T13:37:17+00:00", "type": "hosted", "status": "accepted", "note": "Hosted Repixelizer now enables Patreon alongside Discord. Patreon access policy is title-only: REPIXELIZER_ACCESS_PATREON_TIER_TITLE=Inner Sanctum is sent to Heimdall as patreon_membership_access during backend-callback OAuth start."}
|
||||
{"ts": "2026-04-29T17:20:00+00:00", "type": "implementation", "status": "ok", "note": "Removed the hosted solver loss chart because the explicit solver's loss-like diagnostic is not a useful live objective; solver status now surfaces step, signal, grid alignment, and displacement terms instead."}
|
||||
{"ts": "2026-04-29T17:29:40+00:00", "type": "implementation", "status": "ok", "note": "Hosted GUI now emits explicit service logs for queue saturation, job queue/start/completion/failure/cancel events, and wait/run/total seconds so load pressure shows up in journald instead of only in transient SSE state."}
|
||||
{"ts": "2026-04-29T21:40:11+00:00", "type": "implementation", "status": "ok", "note": "Fixed GUI failed-response handling so submit/config/queue/cancel errors read the Response body once, preserving the real server error instead of throwing 'body stream already read'."}
|
||||
|
|
|
|||
Loading…
Reference in a new issue