diff --git a/src/app/api/admin/import/clone/route.ts b/src/app/api/admin/import/clone/route.ts index e2a5a69e..8b3fcca3 100644 --- a/src/app/api/admin/import/clone/route.ts +++ b/src/app/api/admin/import/clone/route.ts @@ -33,7 +33,14 @@ export const GET = withAdmin( // GET ?source=&action=clonable → all not-yet-present classnames (for "clone all") if (sp.get("action") === "clonable") { - return apiOk({ classnames: await getClonableClassnames(source) }); + try { + return apiOk({ classnames: await getClonableClassnames(source) }); + } catch (err) { + return apiError( + `Failed to fetch source data: ${(err as Error).message}`, + 502, + ); + } } const search = sp.get("search") || ""; @@ -48,12 +55,19 @@ export const GET = withAdmin( ? filterParam : "all"; - const [listResult, stats] = await Promise.all([ - getCloneList({ source, search, page, perPage, filter }), - getCloneStats(source), - ]); + try { + const [listResult, stats] = await Promise.all([ + getCloneList({ source, search, page, perPage, filter }), + getCloneStats(source), + ]); - return apiOk({ items: listResult.items, meta: listResult.meta, stats }); + return apiOk({ items: listResult.items, meta: listResult.meta, stats }); + } catch (err) { + return apiError( + `Failed to fetch source data: ${(err as Error).message}`, + 502, + ); + } }, ); diff --git a/src/lib/services/clone-import.ts b/src/lib/services/clone-import.ts index bbc8021e..8c4891ef 100644 --- a/src/lib/services/clone-import.ts +++ b/src/lib/services/clone-import.ts @@ -106,6 +106,11 @@ export async function fetchSourceFurnidata( } catch { body = await fetchWithFlareSolver(url); } + if (body.trimStart().startsWith("<")) { + throw new Error( + `Source ${url} is behind a Cloudflare challenge that could not be bypassed. Start FlareSolverr and check its logs.`, + ); + } let list: SourceFurni[]; try { const json = JSON.parse(body);