KI-AGENT: Stabilisiert mobilen Session-Start

This commit is contained in:
2026-07-09 07:34:44 +02:00
parent d67da7e02a
commit 14026181c2
3 changed files with 186 additions and 36 deletions

View File

@@ -196,6 +196,7 @@ type RequestOptions = {
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
token?: string | null;
body?: unknown;
timeoutMs?: number;
};
export type MatrixStatus = {
@@ -314,17 +315,46 @@ async function parseJson(response: Response): Promise<unknown> {
}
}
const DEFAULT_REQUEST_TIMEOUT_MS = 15000;
function createTimeoutSignal(timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS): { signal: AbortSignal; cleanup: () => void } {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
return {
signal: controller.signal,
cleanup: () => clearTimeout(timeout),
};
}
function isAbortError(error: unknown): boolean {
return error instanceof Error && error.name === 'AbortError';
}
export async function apiRequest<T>(path: string, options: RequestOptions = {}): Promise<T> {
const hasJsonBody = options.body !== undefined;
const response = await fetch(buildUrl(path), {
method: options.method || 'GET',
headers: {
Accept: 'application/json',
...(hasJsonBody ? { 'Content-Type': 'application/json' } : {}),
...(options.token ? { Authorization: `Bearer ${options.token}` } : {}),
},
body: hasJsonBody ? JSON.stringify(options.body) : undefined,
});
const { signal, cleanup } = createTimeoutSignal(options.timeoutMs);
let response: Response;
try {
response = await fetch(buildUrl(path), {
method: options.method || 'GET',
headers: {
Accept: 'application/json',
...(hasJsonBody ? { 'Content-Type': 'application/json' } : {}),
...(options.token ? { Authorization: `Bearer ${options.token}` } : {}),
},
body: hasJsonBody ? JSON.stringify(options.body) : undefined,
signal,
});
} catch (error) {
if (isAbortError(error)) {
throw new Error(`Zeitüberschreitung beim Verbinden mit dem FEDEO-Server (${path}).`);
}
throw error;
} finally {
cleanup();
}
const payload = await parseJson(response);
@@ -340,14 +370,27 @@ export async function apiRequest<T>(path: string, options: RequestOptions = {}):
}
async function apiFormRequest<T>(path: string, token: string, formData: FormData): Promise<T> {
const response = await fetch(buildUrl(path), {
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: `Bearer ${token}`,
},
body: formData,
});
const { signal, cleanup } = createTimeoutSignal();
let response: Response;
try {
response = await fetch(buildUrl(path), {
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: `Bearer ${token}`,
},
body: formData,
signal,
});
} catch (error) {
if (isAbortError(error)) {
throw new Error(`Zeitüberschreitung beim Hochladen zum FEDEO-Server (${path}).`);
}
throw error;
} finally {
cleanup();
}
const payload = await parseJson(response);