fix(data): 清理旧数据并保护服务端写入

This commit is contained in:
Script Generator
2026-07-02 09:30:50 +08:00
parent 28e0c6de19
commit 916bd17a48
38 changed files with 1346 additions and 194 deletions

View File

@@ -3,6 +3,25 @@ const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001/api/v
let apiAvailable: boolean | null = null;
let probePromise: Promise<boolean> | null = null;
function getErrorMessage(body: unknown, status: number) {
if (typeof body === 'object' && body !== null && 'message' in body) {
const message = (body as { message?: unknown }).message;
if (typeof message === 'string') return message;
if (Array.isArray(message)) return message.join(', ');
}
return `Request failed: ${status}`;
}
export class ApiRequestError extends Error {
constructor(
public readonly status: number,
public readonly body: unknown,
) {
super(getErrorMessage(body, status));
this.name = 'ApiRequestError';
}
}
async function checkApi(): Promise<boolean> {
if (apiAvailable !== null) return apiAvailable;
if (probePromise) return probePromise;
@@ -29,7 +48,7 @@ async function request<T>(path: string, options?: RequestInit): Promise<T> {
if (!res) throw new Error('API 不可用');
if (!res.ok) {
const error = await res.json().catch(() => ({}));
throw new Error(error.message || `请求失败: ${res.status}`);
throw new ApiRequestError(res.status, error);
}
return res.json();
}
@@ -56,7 +75,7 @@ export const api = {
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(err.message || `请求失败: ${res.status}`);
throw new ApiRequestError(res.status, err);
}
return res.json();
} finally {