fix(dev): vite proxy to 127.0.0.1 + throttle error notifications

The dev proxy targeted 'localhost', which Node can resolve to IPv6 ::1 that the
Docker publish doesn't answer after a container recreate — every /api call failed,
spamming 'Network error'. Pin the proxy to 127.0.0.1. Also collapse bursts of
connection/5xx failures into one notification per 30s so a brief restart no longer
floods the notification center.
This commit is contained in:
npeter83 2026-06-11 22:00:57 +02:00
parent 7a189fd163
commit 5598b0cf5b
2 changed files with 22 additions and 15 deletions

View file

@ -68,6 +68,16 @@ class HttpError extends Error {
}
}
// Collapse bursts of connection failures (e.g. while the server restarts) into a
// single notification rather than one per failed request.
let lastErrorNotifiedAt = 0;
function notifyErrorThrottled(title: string, message: string): void {
const now = Date.now();
if (now - lastErrorNotifiedAt < 30_000) return;
lastErrorNotifiedAt = now;
notify({ level: "error", title, message });
}
async function req(url: string, opts: RequestInit = {}): Promise<any> {
const method = opts.method ?? "GET";
let r: Response;
@ -78,22 +88,16 @@ async function req(url: string, opts: RequestInit = {}): Promise<any> {
...opts,
});
} catch (e) {
// Network/connection failure — surface it in the notification center.
notify({
level: "error",
title: "Network error",
message: `Couldn't reach the server (${method} ${url}).`,
});
notifyErrorThrottled(
"Connection lost",
"Couldn't reach the server — it may be restarting. This will clear once it's back."
);
throw e;
}
if (!r.ok) {
// Server faults are worth logging; 401/403/404 etc. are handled by callers.
// Server faults are worth surfacing; 401/403/404 etc. are handled by callers.
if (r.status >= 500) {
notify({
level: "error",
title: `Server error ${r.status}`,
message: `${method} ${url}`,
});
notifyErrorThrottled(`Server error ${r.status}`, `${method} ${url}`);
}
throw new HttpError(r.status);
}

View file

@ -2,10 +2,13 @@ import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// During `vite dev` (host with Node), proxy API calls to the backend container.
// Use 127.0.0.1 (not "localhost") so Node doesn't resolve to IPv6 ::1, which the
// Docker port publish may not answer — that surfaces as proxy connection failures.
const target = "http://127.0.0.1:8080";
const proxy = {
"/api": "http://localhost:8080",
"/auth": "http://localhost:8080",
"/healthz": "http://localhost:8080",
"/api": target,
"/auth": target,
"/healthz": target,
};
export default defineConfig({