diff --git a/internal/anime/service/service.go b/internal/anime/service/service.go index 16479ac..f6e19d7 100644 --- a/internal/anime/service/service.go +++ b/internal/anime/service/service.go @@ -6,6 +6,7 @@ import ( "mal/integrations/jikan" "mal/internal/db" "mal/internal/domain" + "mal/internal/observability" "math/rand" "sort" "strings" @@ -187,6 +188,13 @@ func (s *animeService) GetDiscoverForYou(ctx context.Context, userID string) (do for i := range limit { anime, fetchErr := s.jikan.GetAnimeByID(ctx, rankedIDs[i].id) if fetchErr != nil { + observability.Warn( + "recommendation_anime_fetch_failed", + "anime", + "", + map[string]any{"anime_id": rankedIDs[i].id}, + fetchErr, + ) continue } animes = append(animes, anime) @@ -249,6 +257,13 @@ func (s *animeService) GetAiringSchedule(ctx context.Context, userID string) ([] if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { return nil, err } + observability.Warn( + "schedule_partial_fetch_failed", + "anime", + "", + map[string]any{"user_id": userID, "count": len(ids)}, + err, + ) return animes, nil } diff --git a/internal/playback/service/service.go b/internal/playback/service/service.go index 4d93dc8..5a0c148 100644 --- a/internal/playback/service/service.go +++ b/internal/playback/service/service.go @@ -12,6 +12,7 @@ import ( "mal/integrations/jikan" "mal/internal/db" "mal/internal/domain" + "mal/internal/observability" "mal/pkg/net/limits" "mal/pkg/net/useragent" "net/http" @@ -316,10 +317,12 @@ func (s *playbackService) CompleteAnime(ctx context.Context, userID string, anim } } - _ = s.repo.DeleteContinueWatchingEntry(ctx, db.DeleteContinueWatchingEntryParams{ + if err := s.repo.DeleteContinueWatchingEntry(ctx, db.DeleteContinueWatchingEntryParams{ UserID: userID, AnimeID: animeID, - }) + }); err != nil { + return err + } if err := s.repo.SaveWatchProgress(ctx, db.SaveWatchProgressParams{ UserID: userID, AnimeID: animeID, @@ -328,12 +331,20 @@ func (s *playbackService) CompleteAnime(ctx context.Context, userID string, anim }); err != nil { return err } - _ = s.auditSvc.Record(ctx, domain.AuditEvent{ + if err := s.auditSvc.Record(ctx, domain.AuditEvent{ UserID: userID, Action: "watch_completed", ResourceType: "anime", ResourceID: strconv.FormatInt(animeID, 10), - }) + }); err != nil { + observability.Warn( + "audit_record_failed", + "playback", + "", + map[string]any{"user_id": userID, "anime_id": animeID, "action": "watch_completed"}, + err, + ) + } return nil } diff --git a/internal/watchlist/service/service.go b/internal/watchlist/service/service.go index bbb1f2c..7c85e3f 100644 --- a/internal/watchlist/service/service.go +++ b/internal/watchlist/service/service.go @@ -23,15 +23,18 @@ func (s *watchlistService) UpdateEntry(ctx context.Context, userID string, anime _, err := s.repo.GetAnime(ctx, animeID) if err != nil { anime, err := s.jikan.GetAnimeByID(ctx, int(animeID)) - if err == nil { - _, _ = s.repo.UpsertAnime(ctx, db.UpsertAnimeParams{ - ID: int64(anime.MalID), - TitleOriginal: anime.Title, - TitleEnglish: sql.NullString{String: anime.TitleEnglish, Valid: anime.TitleEnglish != ""}, - TitleJapanese: sql.NullString{String: anime.TitleJapanese, Valid: anime.TitleJapanese != ""}, - ImageUrl: anime.ImageURL(), - Airing: sql.NullBool{Bool: anime.Airing, Valid: true}, - }) + if err != nil { + return err + } + if _, err := s.repo.UpsertAnime(ctx, db.UpsertAnimeParams{ + ID: int64(anime.MalID), + TitleOriginal: anime.Title, + TitleEnglish: sql.NullString{String: anime.TitleEnglish, Valid: anime.TitleEnglish != ""}, + TitleJapanese: sql.NullString{String: anime.TitleJapanese, Valid: anime.TitleJapanese != ""}, + ImageUrl: anime.ImageURL(), + Airing: sql.NullBool{Bool: anime.Airing, Valid: true}, + }); err != nil { + return err } } @@ -96,10 +99,12 @@ func (s *watchlistService) GetContinueWatchingEntry(ctx context.Context, userID } func (s *watchlistService) DeleteContinueWatching(ctx context.Context, userID string, animeID int64) error { - _ = s.repo.DeleteContinueWatchingEntry(ctx, db.DeleteContinueWatchingEntryParams{ + if err := s.repo.DeleteContinueWatchingEntry(ctx, db.DeleteContinueWatchingEntryParams{ UserID: userID, AnimeID: animeID, - }) + }); err != nil { + return err + } return s.repo.SaveWatchProgress(ctx, db.SaveWatchProgressParams{ UserID: userID, AnimeID: animeID,