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:
parent
bc9b9a854c
commit
3f4d5ed9d7
2 changed files with 22 additions and 15 deletions
|
|
@ -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> {
|
async function req(url: string, opts: RequestInit = {}): Promise<any> {
|
||||||
const method = opts.method ?? "GET";
|
const method = opts.method ?? "GET";
|
||||||
let r: Response;
|
let r: Response;
|
||||||
|
|
@ -78,22 +88,16 @@ async function req(url: string, opts: RequestInit = {}): Promise<any> {
|
||||||
...opts,
|
...opts,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Network/connection failure — surface it in the notification center.
|
notifyErrorThrottled(
|
||||||
notify({
|
"Connection lost",
|
||||||
level: "error",
|
"Couldn't reach the server — it may be restarting. This will clear once it's back."
|
||||||
title: "Network error",
|
);
|
||||||
message: `Couldn't reach the server (${method} ${url}).`,
|
|
||||||
});
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
if (!r.ok) {
|
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) {
|
if (r.status >= 500) {
|
||||||
notify({
|
notifyErrorThrottled(`Server error ${r.status}`, `${method} ${url}`);
|
||||||
level: "error",
|
|
||||||
title: `Server error ${r.status}`,
|
|
||||||
message: `${method} ${url}`,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
throw new HttpError(r.status);
|
throw new HttpError(r.status);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,13 @@ import { defineConfig } from "vite";
|
||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
|
|
||||||
// During `vite dev` (host with Node), proxy API calls to the backend container.
|
// 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 = {
|
const proxy = {
|
||||||
"/api": "http://localhost:8080",
|
"/api": target,
|
||||||
"/auth": "http://localhost:8080",
|
"/auth": target,
|
||||||
"/healthz": "http://localhost:8080",
|
"/healthz": target,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue