albums: ask the artist's own discography before deciding a record does not exist

"A ? of WHEN" opened as a bare local page — no plays, no listeners, no real
release date — while the artist page's expander showed all three for the same
record. The artist page was right and the resolve was wrong.

Deezer's SEARCH index is not the discography. The artist page merges a
MusicBrainz supplement on top of it, and MB-only records get a real id, a real
release date and full Last.fm figures there; the Deezer search that
openAlbumByName ran simply cannot see them. So the resolve now falls through
to the artist's own album list before giving up.

That list has to be the SUPPLEMENTED one. getCatalogArtistPage returns the raw
Deezer page until the artist page has been visited and written the merged
version back into the cache, so a cold click still missed. It now runs
mergeArtistIdentity itself — the same pure merge the artist page and the Now
Playing panel already share — instead of concluding the record is nowhere.

Verified against the artist page's own numbers: id 5831190465731370, released
2026-07-10, 4,521 plays, 236 listeners, per-track 66/131/113/108 — identical
to the expander. The local-composition path stays as the last resort for a
record genuinely in neither catalogue, where it is still the only thing that
can render at all.
This commit is contained in:
KeelrLeek committed 2026-08-01 07:53:57 -05:00
1 parent dde8c7510b
commit f8f56f4398
1 file changed
+47 -4
+47 -4
View File
@@ -2558,12 +2558,55 @@ export async function openAlbumByName(artist, title, opts = {}) {
if (request !== albumResolveRequest) return null;
// A title-only or first-result fallback can cross into a namesake's
// catalog. Without a verified id, both artist and title must match.
const match = res.albums?.find(
let match = res.albums?.find(
(album) => catNorm(album.artist) === na && catNorm(album.title) === nt,
);
// A successful search that matched nothing is an answer ABOUT THE
// RECORD: this artist has no such album in the catalog. Negative-cache
// it. A throw below is an answer about the network, and is not cached.
// Deezer's SEARCH index is not the whole discography. The artist page
// merges a MusicBrainz supplement on top of it, so records Deezer does
// not carry at all still have a real id, a real release date and full
// Last.fm figures there — Panda Bear's "A ? of WHEN" is one, and it is
// exactly what made this resolve give up and fall through to a bare
// local page. Ask the ARTIST'S OWN discography before concluding the
// record does not exist; it is the same list the artist page's album
// expander opens from, and it is already cached whenever that page has
// been visited.
if (!match) {
const seed = await resolveArtistSeedByName(artist);
if (request !== albumResolveRequest) return null;
if (seed?.id != null) {
const page = await getCatalogArtistPage(seed.id).catch(() => null);
if (request !== albumResolveRequest) return null;
match = page?.albums?.find((album) => catNorm(album.title) === nt);
// The cached page is only SUPPLEMENTED once the artist page
// has been visited — cold, it is the raw Deezer list and the
// MB-only records are still missing. Run the same merge the
// artist page and the Now Playing panel run, rather than
// concluding the record does not exist.
if (!match) {
const identity = await api
.catalogArtistIdentity(seed.id, seed.name ?? artist)
.catch(() => null);
if (request !== albumResolveRequest) return null;
if (identity?.albums?.length) {
const merged = mergeArtistIdentity(
{
artist: { name: seed.name ?? artist },
albums: page?.albums ?? [],
socials: [],
typeHints: [],
},
identity,
);
match = merged?.albums?.find(
(album) => catNorm(album.title) === nt,
);
}
}
}
}
// A settled miss is an answer ABOUT THE RECORD: neither the catalog nor
// the artist's own discography has it. Negative-cache that. A throw
// below is an answer about the network, and is not cached.
albumNameResolves.set(key, match ? match.id : null);
if (!match) return null;
openCatalogAlbum(match.id, opts);