Files
openclaw/extensions/qa-lab/web/src/http.ts
T
2026-07-27 14:05:14 +08:00

73 lines
2.1 KiB
TypeScript

const QA_LAB_API_REQUEST_TIMEOUT_MS = 30_000;
function createRequestSignal(): AbortSignal {
return AbortSignal.timeout(QA_LAB_API_REQUEST_TIMEOUT_MS);
}
async function readJsonResponse<T>(response: Response, label: string): Promise<T> {
const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
if (contentType && contentType !== "application/json" && !contentType.endsWith("+json")) {
throw new Error(`${label}: expected JSON response`);
}
const text = await response.text();
if (!text.trim()) {
throw new Error(`${label}: empty JSON response`);
}
try {
return JSON.parse(text) as T;
} catch (cause) {
throw new Error(`${label}: malformed JSON response`, { cause });
}
}
export async function getJson<T>(path: string): Promise<T> {
const response = await fetch(path, { signal: createRequestSignal() });
if (!response.ok) {
throw new Error(`${response.status} ${response.statusText}`);
}
return await readJsonResponse<T>(response, path);
}
export async function getJsonNoStore<T>(path: string): Promise<T> {
const response = await fetch(path, {
cache: "no-store",
signal: createRequestSignal(),
});
if (!response.ok) {
throw new Error(`${response.status} ${response.statusText}`);
}
return await readJsonResponse<T>(response, path);
}
export async function postJson<T>(path: string, body: unknown): Promise<T> {
const response = await fetch(path, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(body),
signal: createRequestSignal(),
});
if (!response.ok) {
const payload: { error?: string } = await readJsonResponse<{ error?: string }>(
response,
path,
).catch(() => ({}));
throw new QaLabHttpError(
payload.error || `${response.status} ${response.statusText}`,
response.status,
payload,
);
}
return await readJsonResponse<T>(response, path);
}
export class QaLabHttpError extends Error {
constructor(
message: string,
readonly status: number,
readonly payload: unknown,
) {
super(message);
this.name = "QaLabHttpError";
}
}