corpus

Log | Files | Refs | README | LICENSE

commit 304c446cb01f7d37aa004bae05030534e0a3fe15
parent 8b8811d7e2c0cf6fe4e57880ef8d0b82470a7563
Author: mtmn <miro@haravara.org>
Date:   Wed, 22 Apr 2026 23:57:51 +0200

fix: unhandled last.fm errors

Diffstat:
Msrc/Cover.purs | 26+++++++++++++-------------
Msrc/Sync.purs | 74++++++++++++++++++++++++++++++++++++++++++++------------------------------
2 files changed, 57 insertions(+), 43 deletions(-)

diff --git a/src/Cover.purs b/src/Cover.purs @@ -123,19 +123,19 @@ coverSources mbid artist release mVariant cfg = ] in caaSource <> - [ { name: "lastfm" - , s3Key: "covers/lastfm/" <> safeArtist <> "-" <> safeRelease <> ".avif" - , findUrl: - if artist == "" || release == "" then pure Nothing - else fetchLastfmCoverUrl cfg artist release - } - , { name: "discogs" - , s3Key: "covers/discogs/" <> safeArtist <> "-" <> safeRelease <> ".avif" - , findUrl: - if artist == "" || release == "" then pure Nothing - else fetchDiscogsCoverUrl cfg artist release - } - ] + [ { name: "lastfm" + , s3Key: "covers/lastfm/" <> safeArtist <> "-" <> safeRelease <> ".avif" + , findUrl: + if artist == "" || release == "" then pure Nothing + else fetchLastfmCoverUrl cfg artist release + } + , { name: "discogs" + , s3Key: "covers/discogs/" <> safeArtist <> "-" <> safeRelease <> ".avif" + , findUrl: + if artist == "" || release == "" then pure Nothing + else fetchDiscogsCoverUrl cfg artist release + } + ] serveCover :: (Response -> Effect Unit) -> UserConfig -> String -> URL -> Response -> Aff Unit serveCover serveNotFound cfg slug url res = do diff --git a/src/Sync.purs b/src/Sync.purs @@ -227,46 +227,60 @@ lfSync conn apiKey lfmUser slug writeLock = do where performLastfmSync = do Log.info $ "Starting Last.fm sync for " <> lfmUser - { tracks, totalPages } <- fetchLastfmPage apiKey lfmUser 1 Nothing - Tuple added hitCount <- withTransaction conn writeLock (processLastfmTracks tracks) - Log.info $ "Last.fm page 1/" <> show totalPages <> ": added " <> show added <> ", " <> show hitCount <> " already present." - let - validTracks = mapMaybe lastfmTrackToListen tracks - allExist = hitCount == length validTracks && not (null validTracks) - if allExist || totalPages <= 1 then do - when (added > 0) $ Log.info $ "Last.fm sync complete. Added " <> show added <> " new scrobbles." - recordSyncSuccess slug "lastfm" added - else do - total <- paginateLastfmUntilDone 2 totalPages Nothing added - Log.info $ "Last.fm sync complete. Added " <> show total <> " new scrobbles." - recordSyncSuccess slug "lastfm" total + res <- try $ fetchLastfmPage apiKey lfmUser 1 Nothing + case res of + Left err -> do + Log.error $ "Last.fm sync fetch error: " <> Exception.message err + liftEffect $ Metrics.incSyncRuns slug "lastfm" "error" + Right { tracks, totalPages } -> do + Tuple added hitCount <- withTransaction conn writeLock (processLastfmTracks tracks) + Log.info $ "Last.fm page 1/" <> show totalPages <> ": added " <> show added <> ", " <> show hitCount <> " already present." + let + validTracks = mapMaybe lastfmTrackToListen tracks + allExist = hitCount == length validTracks && not (null validTracks) + if allExist || totalPages <= 1 then do + when (added > 0) $ Log.info $ "Last.fm sync complete. Added " <> show added <> " new scrobbles." + recordSyncSuccess slug "lastfm" added + else do + total <- paginateLastfmUntilDone 2 totalPages Nothing added + Log.info $ "Last.fm sync complete. Added " <> show total <> " new scrobbles." + recordSyncSuccess slug "lastfm" total paginateLastfmUntilDone page totalPages mTo acc | page > totalPages = pure acc | otherwise = do Log.info $ "Fetching Last.fm page " <> show page <> "/" <> show totalPages <> "..." - { tracks } <- fetchLastfmPage apiKey lfmUser page mTo - Tuple added hitCount <- withTransaction conn writeLock (processLastfmTracks tracks) - Log.info $ "Last.fm page " <> show page <> "/" <> show totalPages <> ": added " <> show added <> ", " <> show hitCount <> " already present." - let - validTracks = mapMaybe lastfmTrackToListen tracks - allExist = hitCount == length validTracks && not (null validTracks) - if allExist || null tracks then pure (acc + added) - else paginateLastfmUntilDone (page + 1) totalPages mTo (acc + added) + res <- try $ fetchLastfmPage apiKey lfmUser page mTo + case res of + Left err -> do + Log.error $ "Last.fm sync fetch error: " <> Exception.message err + pure acc + Right { tracks } -> do + Tuple added hitCount <- withTransaction conn writeLock (processLastfmTracks tracks) + Log.info $ "Last.fm page " <> show page <> "/" <> show totalPages <> ": added " <> show added <> ", " <> show hitCount <> " already present." + let + validTracks = mapMaybe lastfmTrackToListen tracks + allExist = hitCount == length validTracks && not (null validTracks) + if allExist || null tracks then pure (acc + added) + else paginateLastfmUntilDone (page + 1) totalPages mTo (acc + added) performLastfmBackfill = do mOldest <- getOldestTs conn for_ mOldest \oldestTs -> do Log.info $ "Checking for Last.fm history before " <> show oldestTs <> "..." - { tracks, totalPages } <- fetchLastfmPage apiKey lfmUser 1 (Just (oldestTs - 1)) - if null tracks then - Log.info "No older Last.fm history found." - else do - Log.info $ "Backfilling " <> show totalPages <> " pages of Last.fm history before " <> show oldestTs - Tuple added hitCount <- withTransaction conn writeLock (processLastfmTracks tracks) - Log.info $ "Last.fm backfill page 1/" <> show totalPages <> ": added " <> show added <> ", " <> show hitCount <> " already present." - total <- paginateLastfmUntilDone 2 totalPages (Just (oldestTs - 1)) added - Log.info $ "Last.fm backfill complete. Added " <> show total <> " older scrobbles." + res <- try $ fetchLastfmPage apiKey lfmUser 1 (Just (oldestTs - 1)) + case res of + Left err -> + Log.error $ "Last.fm backfill fetch error: " <> Exception.message err + Right { tracks, totalPages } -> + if null tracks then + Log.info "No older Last.fm history found." + else do + Log.info $ "Backfilling " <> show totalPages <> " pages of Last.fm history before " <> show oldestTs + Tuple added hitCount <- withTransaction conn writeLock (processLastfmTracks tracks) + Log.info $ "Last.fm backfill page 1/" <> show totalPages <> ": added " <> show added <> ", " <> show hitCount <> " already present." + total <- paginateLastfmUntilDone 2 totalPages (Just (oldestTs - 1)) added + Log.info $ "Last.fm backfill complete. Added " <> show total <> " older scrobbles." processLastfmTracks tracks = do s <- foldM step { added: 0, hitCount: 0 } (mapMaybe lastfmTrackToListen tracks)