fix: auto-logout on 401, raise nginx timeout for nc-scan
401 Unauthorized loop: - client.ts had no 401 handler, leaving stale expired tokens in localStorage. The PrivateRoute guard only checked token existence, so the app would render but every API call would fail silently. - Fix: on any 401 response, clear the token and redirect to /login. 504 Gateway Timeout on nc-scan: - nginx default proxy_read_timeout is 60s. The scan endpoint makes one Nextcloud request per audio file (list + metadata), which easily exceeds that on larger libraries. - Fix: add a dedicated location block for nc-scan with 300s timeouts. General /api/ block gets explicit 60s timeouts for clarity. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,21 @@ server {
|
|||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# NC scan hits Nextcloud for every file — can take several minutes on large libraries
|
||||||
|
location ~ ^/api/v1/bands/[^/]+/nc-scan {
|
||||||
|
proxy_pass http://api:8000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
proxy_read_timeout 300s;
|
||||||
|
proxy_send_timeout 300s;
|
||||||
}
|
}
|
||||||
|
|
||||||
# SPA routing — all other paths fall back to index.html
|
# SPA routing — all other paths fall back to index.html
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ async function request<T>(
|
|||||||
}
|
}
|
||||||
const resp = await fetch(`${BASE}${path}`, { ...options, headers });
|
const resp = await fetch(`${BASE}${path}`, { ...options, headers });
|
||||||
if (!resp.ok) {
|
if (!resp.ok) {
|
||||||
|
if (resp.status === 401) {
|
||||||
|
clearToken();
|
||||||
|
window.location.href = "/login";
|
||||||
|
throw new Error("Session expired");
|
||||||
|
}
|
||||||
const error = await resp.json().catch(() => ({ detail: resp.statusText }));
|
const error = await resp.json().catch(() => ({ detail: resp.statusText }));
|
||||||
throw new Error(error.detail ?? resp.statusText);
|
throw new Error(error.detail ?? resp.statusText);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user