mirror of
https://github.com/ZSeven-W/openpencil.git
synced 2026-06-01 03:14:29 +07:00
fix(ai): swallow image-search network failures into the existing fallback
`fetchFromOpenverse` and `fetchFromWikimedia` were missing try/catch, so a ConnectTimeoutError on `api.openverse.org` (frequent on networks that can't reach Openverse) bubbled up to nitro's default handler and turned a single image-search lookup into a HTTP 500 for the whole design generation flow. The handler already treats `null` (Openverse) and `[]` (Wikimedia) as the documented fallback signals — wrap the fetches and return those on any throw, plus an explicit 8s AbortSignal.timeout so the wait is bounded.
This commit is contained in:
parent
a727632a63
commit
a5952bc88b
1 changed files with 35 additions and 16 deletions
|
|
@ -254,17 +254,29 @@ async function fetchFromOpenverse(
|
|||
}
|
||||
}
|
||||
|
||||
const res = await fetch(url.toString(), { headers });
|
||||
if (res.status === 429) {
|
||||
// Rate limited — signal fallback
|
||||
return null;
|
||||
}
|
||||
if (!res.ok) {
|
||||
return null;
|
||||
}
|
||||
// Network failures (ConnectTimeoutError on restricted networks, DNS
|
||||
// failures, etc.) need to behave like a 429: return null so the caller
|
||||
// falls back to Wikimedia. Without this, fetch() throws, the throw
|
||||
// bubbles up to nitro's default handler, and the user sees a 500
|
||||
// instead of placeholder images.
|
||||
try {
|
||||
const res = await fetch(url.toString(), {
|
||||
headers,
|
||||
signal: AbortSignal.timeout(8000),
|
||||
});
|
||||
if (res.status === 429) {
|
||||
// Rate limited — signal fallback
|
||||
return null;
|
||||
}
|
||||
if (!res.ok) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = (await res.json()) as OpenverseSearchResponse;
|
||||
return (data.results ?? []).map(mapOpenverseResult);
|
||||
const data = (await res.json()) as OpenverseSearchResponse;
|
||||
return (data.results ?? []).map(mapOpenverseResult);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchFromWikimedia(query: string, count: number): Promise<ImageSearchResult[]> {
|
||||
|
|
@ -280,14 +292,21 @@ async function fetchFromWikimedia(query: string, count: number): Promise<ImageSe
|
|||
url.searchParams.set('format', 'json');
|
||||
url.searchParams.set('origin', '*');
|
||||
|
||||
const res = await fetch(url.toString());
|
||||
if (!res.ok) return [];
|
||||
// Same network-failure shielding as Openverse: an empty result is the
|
||||
// documented fallback signal, returning [] keeps the endpoint at 200
|
||||
// with placeholder-friendly results instead of bubbling the throw.
|
||||
try {
|
||||
const res = await fetch(url.toString(), { signal: AbortSignal.timeout(8000) });
|
||||
if (!res.ok) return [];
|
||||
|
||||
const data = (await res.json()) as WikimediaQueryResponse;
|
||||
const pages = data.query?.pages;
|
||||
if (!pages) return [];
|
||||
const data = (await res.json()) as WikimediaQueryResponse;
|
||||
const pages = data.query?.pages;
|
||||
if (!pages) return [];
|
||||
|
||||
return mapWikimediaPages(pages);
|
||||
return mapWikimediaPages(pages);
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue