sync: phase 1 backend + frontend from server
This commit is contained in:
+18
-3
@@ -1,12 +1,17 @@
|
||||
const API_BASE = '/api/v1';
|
||||
|
||||
export interface ApiError extends Error {
|
||||
status?: number;
|
||||
retryAfter?: number;
|
||||
}
|
||||
|
||||
async function request<T>(method: string, path: string, body?: unknown): Promise<T> {
|
||||
const headers: Record<string, string> = {};
|
||||
if (body !== undefined) {
|
||||
headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
|
||||
const response = await fetch(`${API_BASE}${path}`, {
|
||||
const response = await fetch(API_BASE + path, {
|
||||
method,
|
||||
headers,
|
||||
credentials: 'include',
|
||||
@@ -14,7 +19,8 @@ async function request<T>(method: string, path: string, body?: unknown): Promise
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
let errorMessage = `Request failed: ${response.status}`;
|
||||
let errorMessage = 'Request failed: ' + response.status;
|
||||
let retryAfter: number | undefined;
|
||||
try {
|
||||
const errorData = await response.json();
|
||||
if (typeof errorData?.message === 'string') {
|
||||
@@ -22,10 +28,19 @@ async function request<T>(method: string, path: string, body?: unknown): Promise
|
||||
} else if (typeof errorData?.error === 'string') {
|
||||
errorMessage = errorData.error;
|
||||
}
|
||||
if (response.status === 429 && typeof errorData?.retry_after === 'number') {
|
||||
retryAfter = errorData.retry_after;
|
||||
}
|
||||
} catch {
|
||||
// ignore parse error
|
||||
}
|
||||
throw new Error(errorMessage);
|
||||
const err = new Error(errorMessage) as ApiError;
|
||||
err.status = response.status;
|
||||
if (response.status === 429) {
|
||||
const ra = response.headers.get('Retry-After');
|
||||
err.retryAfter = retryAfter ?? (ra ? parseInt(ra, 10) : undefined);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (response.status === 204) {
|
||||
|
||||
Reference in New Issue
Block a user