fix: improve error handling for Cloudflare-protected clone sources
CI / check (push) Successful in 26s
CI / release (push) Skipped
CI / deploy (push) Successful in 54s

- Detect HTML responses from FlareSolverr and throw descriptive error
  instead of letting JSON.parse fail with cryptic 'Unexpected token' error
- Add try/catch to clone/route.ts GET handler to return 502 with
  clear message instead of Internal Server Error 500
- Add FLARESOLVERR_URL to .env
This commit is contained in:
openhands committed 2026-08-04 19:21:31 +02:00
1 parent 0abcead359
commit 1fd6f7146b
2 files changed
+25 -6

No files matched your search

+20 -6
View File
@@ -33,7 +33,14 @@ export const GET = withAdmin(
// GET ?source=<id>&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,
);
}
},
);
+5
View File
@@ -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);