Make project service resilient with timeout and localStorage fallback

cgen-0a88274abfc64dc5b2fc449daf876ffe
This commit is contained in:
Builder.io 2025-09-27 21:57:41 +00:00
parent 85340a094f
commit 38367daebe

View file

@ -243,68 +243,128 @@ export const aethexUserService = {
// Project Services
export const aethexProjectService = {
async getUserProjects(userId: string): Promise<AethexProject[]> {
const { data, error } = await supabase
.from("projects")
.select("*")
.eq("user_id", userId)
.order("created_at", { ascending: false });
try {
const { data, error } = await supabase
.from("projects")
.select("*")
.eq("user_id", userId)
.order("created_at", { ascending: false });
if (error) {
console.warn("Error fetching projects:", error);
return [];
if (!error && Array.isArray(data)) {
return data as AethexProject[];
}
if (error) console.warn("Error fetching projects:", error);
} catch (err) {
console.warn("Exception fetching projects, using local fallback:", err);
}
return data as AethexProject[];
try {
const raw = localStorage.getItem("mock_projects");
const all = raw ? (JSON.parse(raw) as AethexProject[]) : [];
return all.filter((p) => p.user_id === userId).sort((a, b) => (b.created_at || "").localeCompare(a.created_at || ""));
} catch {
return [];
}
},
async createProject(
project: Omit<AethexProject, "id" | "created_at" | "updated_at">,
): Promise<AethexProject | null> {
const { data, error } = await supabase
.from("projects")
.insert(project)
.select()
.single();
try {
const supabasePromise = supabase
.from("projects")
.insert(project)
.select()
.single();
if (error) {
console.warn("Error creating project:", error);
throw error;
const timeout = new Promise<any>((resolve) =>
setTimeout(() => resolve({ data: null, error: new Error("timeout") }), 6000)
);
const { data, error } = await (Promise.race([supabasePromise as any, timeout]) as Promise<any>);
if (!error && data) {
return data as AethexProject;
}
if (error) console.warn("Create project failed or timed out, using local fallback:", error?.message || error);
} catch (err: any) {
console.warn("Create project exception, using local fallback:", err?.message || err);
}
return data as AethexProject;
const now = new Date().toISOString();
const localProject: AethexProject = {
...(project as any),
id: `local_${Date.now()}_${Math.random().toString(36).slice(2)}`,
created_at: now,
updated_at: now,
} as AethexProject;
try {
const raw = localStorage.getItem("mock_projects");
const list: AethexProject[] = raw ? JSON.parse(raw) : [];
list.unshift(localProject);
localStorage.setItem("mock_projects", JSON.stringify(list));
} catch {}
return localProject;
},
async updateProject(
projectId: string,
updates: Partial<AethexProject>,
): Promise<AethexProject | null> {
const { data, error } = await supabase
.from("projects")
.update(updates)
.eq("id", projectId)
.select()
.single();
try {
const { data, error } = await supabase
.from("projects")
.update(updates)
.eq("id", projectId)
.select()
.single();
if (error) {
console.warn("Error updating project:", error);
throw error;
if (!error && data) return data as AethexProject;
if (error) console.warn("Error updating project:", error);
} catch (err) {
console.warn("Exception updating project, using local fallback:", err);
}
return data as AethexProject;
try {
const raw = localStorage.getItem("mock_projects");
const list: AethexProject[] = raw ? JSON.parse(raw) : [];
const idx = list.findIndex((p) => (p as any).id === projectId);
if (idx >= 0) {
const updated = { ...list[idx], ...updates, updated_at: new Date().toISOString() } as AethexProject;
list[idx] = updated;
localStorage.setItem("mock_projects", JSON.stringify(list));
return updated;
}
} catch {}
return null;
},
async deleteProject(projectId: string): Promise<boolean> {
const { error } = await supabase
.from("projects")
.delete()
.eq("id", projectId);
if (error) {
console.warn("Error deleting project:", error);
return false;
try {
const { error } = await supabase
.from("projects")
.delete()
.eq("id", projectId);
if (!error) return true;
if (error) console.warn("Error deleting project:", error);
} catch (err) {
console.warn("Exception deleting project, using local fallback:", err);
}
return true;
try {
const raw = localStorage.getItem("mock_projects");
const list: AethexProject[] = raw ? JSON.parse(raw) : [];
const next = list.filter((p) => (p as any).id !== projectId);
localStorage.setItem("mock_projects", JSON.stringify(next));
return true;
} catch {}
return false;
},
async getAllProjects(limit = 10): Promise<AethexProject[]> {