From 22955c0018d88f31afd4245dce79e1f6183eaeec Mon Sep 17 00:00:00 2001 From: mkelvers Date: Wed, 8 Apr 2026 17:17:14 +0200 Subject: [PATCH] fix: handle jikan rate limits gracefully instead of dropping data --- internal/features/anime/service.go | 5 +++-- internal/worker/relations.go | 17 ++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/internal/features/anime/service.go b/internal/features/anime/service.go index 8b119d5..29832dc 100644 --- a/internal/features/anime/service.go +++ b/internal/features/anime/service.go @@ -79,8 +79,9 @@ func (s *Service) GetWatchingAnime(ctx context.Context, userID string) ([]templa for _, row := range rows { anime, err := s.jikanClient.GetAnimeByID(int(row.AnimeID)) if err != nil { - // Skip if we can't fetch anime details - continue + // Instead of skipping, we still append it, but without the extra Jikan details + // This prevents anime from vanishing from the watchlist when Jikan rate limits us. + anime = jikan.Anime{} } result = append(result, templates.WatchingAnimeWithDetails{ Entry: row, diff --git a/internal/worker/relations.go b/internal/worker/relations.go index 02a4fc8..235d990 100644 --- a/internal/worker/relations.go +++ b/internal/worker/relations.go @@ -71,7 +71,16 @@ func (w *Worker) syncRelations(ctx context.Context) { for _, a := range animes { func() { - // Always mark as synced and sleep so the queue advances even on error. + animeData, err := w.client.GetAnimeByID(int(a.ID)) + if err != nil { + log.Printf("worker: failed to fetch anime details for %d: %v", a.ID, err) + // Sleep a bit on error to respect rate limits, but DO NOT mark as synced + // so it will be retried on the next worker run. + time.Sleep(2 * time.Second) + return + } + + // If we got here, we successfully fetched the data, so we mark it as synced. defer func() { err := w.db.MarkRelationsSynced(ctx, a.ID) if err != nil { @@ -80,12 +89,6 @@ func (w *Worker) syncRelations(ctx context.Context) { time.Sleep(400 * time.Millisecond) }() - animeData, err := w.client.GetAnimeByID(int(a.ID)) - if err != nil { - log.Printf("worker: failed to fetch anime details for %d: %v", a.ID, err) - return - } - for _, rel := range animeData.Relations { for _, entry := range rel.Entry { if entry.Type == "anime" {