datawhalechina/hello-agents · error · ApiError
推荐失败
Error message
推荐失败
What it means
'推荐失败' (recommendation failed) is thrown in beep-YingQian's HomePage when the wrapped recommendation API postRecommend() resolves with success=false or no data — i.e. the HTTP call succeeded but the application-level envelope marks it a failure, or the envelope lacked any message. The catch also reuses the string as the generic user-facing fallback when a non-Error value is thrown.
Source
Thrown at Co-creation-projects/aatanxiao12-beep-YingQian/frontend/src/pages/HomePage.tsx:90
const seen = loadSeen()
const merged: RecommendRequest = {
...request,
exclude_titles: [
...new Set([
...request.exclude_titles,
...seen.map((s) => s.title),
]),
],
exclude_ids: [
...new Set([...request.exclude_ids, ...seen.map((s) => s.id)]),
],
}
try {
const res = await postRecommend(merged)
if (!res.success || !res.data) {
throw new ApiError(res.message || '推荐失败')
}
setStageIndex(PROGRESS_STAGES.length - 1)
saveSession({
request: merged,
result: res.data,
message: res.message,
})
navigate('/result')
} catch (err) {
setError(err instanceof Error ? err.message : '推荐失败,请稍后重试')
} finally {
stopFakeProgress()
setLoading(false)
}
}
return (View on GitHub (pinned to 606a07d341)
Solutions
- Inspect the actual response in DevTools — when success=false the backend message (if any) names the real cause and this error only fires when it's absent.
- If exclusions exhausted the pool, reset the session (clear saved seen/exclude state in sessionId storage) or relax exclude merging for cold-start users.
- Check backend logs for the recommender service; success=false often wraps an upstream model failure.
- Make the backend always return a non-empty message so users see the specific cause instead of this generic string.
Defensive patterns
Strategy: validation
Validate before calling
const seenCount = seen.length;
if (seenCount > MAX_EXCLUSIONS) {
// pool likely exhausted; drop oldest exclusions
seen.splice(0, seenCount - MAX_EXCLUSIONS);
}
if (!request || !Array.isArray(request.exclude_ids)) {
throw new Error('推荐请求缺少排除列表');
} Type guard
function isRecommendSuccess(res: unknown): res is { success: true; data: NonNullable<unknown>; message?: string } {
return typeof res === 'object' && res !== null
&& (res as { success?: unknown }).success === true
&& 'data' in (res as object);
} Try / catch
try {
const res = await postRecommend(merged);
if (!isRecommendSuccess(res)) {
showNotice(res?.message || '暂无更多推荐,请调整偏好后重试');
return;
}
// success path
} catch (err) {
setError(err instanceof Error ? err.message : '推荐失败,请稍后重试');
} Prevention
- Cap exclude_ids/seen lists so the candidate pool can't be exhausted by heavy use.
- Treat success=false with empty data as an empty state, not an exception, when the backend message says so.
- Confirm the backend always populates message on failure so generic text never appears.
When it happens
Trigger: POST to the recommend endpoint returns 200 with {success:false, message?} — backend couldn't build a recommendation (e.g. insufficient watched-movie history, all candidates excluded by exclude_titles/exclude_ids, upstream recommender/LLM error) — or returns success:true with data missing. The merged request dedupes exclude_ids with previously seen titles, so an over-excluded user can exhaust the candidate pool.
Common situations: New user with no history so the recommender has nothing to rank; user clicked '换一批' (change batch) repeatedly in a prior session so seen-list exclusions eliminated all candidates; backend message field empty so the generic text is shown.
Related errors
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/8bad238466b881e0.
Report an issue: GitHub.