refactor(client): centralize error feedback with toast events

- emit API/network failures through a shared toast event bridge

- remove per-page inline error notifications to avoid duplicate error UI

- dedupe repeated toast messages to keep feedback readable
This commit is contained in:
2026-04-10 22:24:30 +03:00
parent 7444082b65
commit ccce3381c1
25 changed files with 59 additions and 80 deletions
+15 -5
View File
@@ -11,19 +11,29 @@ import type {
ScenarioStep,
Snippet,
} from './types';
import { emitApiErrorToast } from '../lib/toast-events';
// In dev, Vite proxies /environments /sessions /scenarios to localhost:3000.
// In production (or when VITE_API_URL is set) we hit the configured origin directly.
const BASE_URL: string = (import.meta.env.VITE_API_URL as string | undefined) ?? '';
async function request<T>(path: string, init?: RequestInit): Promise<T> {
const res = await fetch(`${BASE_URL}${path}`, {
headers: { 'Content-Type': 'application/json', ...init?.headers },
...init,
});
let res: Response;
try {
res = await fetch(`${BASE_URL}${path}`, {
headers: { 'Content-Type': 'application/json', ...init?.headers },
...init,
});
} catch (err) {
const message = (err as Error).message || 'Network request failed';
emitApiErrorToast(message);
throw new Error(message);
}
if (!res.ok) {
const text = await res.text().catch(() => res.statusText);
throw new Error(`${res.status} ${text}`);
const message = `${res.status} ${text}`;
emitApiErrorToast(message);
throw new Error(message);
}
const contentLength = res.headers.get('content-length');
if (res.status === 204 || contentLength === '0') return undefined as T;