From f1d3ba99f19d16107517177a68bcdae17c1cd616 Mon Sep 17 00:00:00 2001 From: rowkav09 Date: Sat, 3 Oct 2026 22:16:04 +0100 Subject: [PATCH] Ignore null and malformed Genre entries when reading Plex tracks A track whose Genre list has a null entry, or a Genre value that is not a list, made libraryTracks throw a raw TypeError and fail the whole page. Now only string tags in a real list are used, so one odd row no longer breaks the sync. --- packages/plex/src/client.genre-rows.test.ts | 34 +++++++++++++++++++++ packages/plex/src/client.ts | 4 +-- 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 packages/plex/src/client.genre-rows.test.ts diff --git a/packages/plex/src/client.genre-rows.test.ts b/packages/plex/src/client.genre-rows.test.ts new file mode 100644 index 0000000..e613ea8 --- /dev/null +++ b/packages/plex/src/client.genre-rows.test.ts @@ -0,0 +1,34 @@ +import { afterEach, expect, it, vi } from 'vitest' +import { PlexClient } from './client.js' + +afterEach(() => { + vi.unstubAllGlobals() +}) + +const track = (Genre: unknown) => ({ + ratingKey: 1, + title: 'Song', + parentRatingKey: 2, + parentTitle: 'Album', + grandparentRatingKey: 3, + grandparentTitle: 'Artist', + Genre, +}) + +function serve(Genre: unknown) { + vi.stubGlobal( + 'fetch', + async () => new Response(JSON.stringify({ MediaContainer: { totalSize: 1, Metadata: [track(Genre)] } })), + ) + return new PlexClient('http://plex.test:32400', 'tok') +} + +it('skips a null entry in a track Genre list instead of throwing', async () => { + const page = await serve([{ tag: 'Rock' }, null, { tag: ' Jazz ' }]).libraryTracks('1', 0, 50) + expect(page.items[0]?.genres).toEqual(['Rock', 'Jazz']) +}) + +it('treats a Genre value that is not a list as no genres', async () => { + const page = await serve({ tag: 'Rock' }).libraryTracks('1', 0, 50) + expect(page.items[0]?.genres).toEqual([]) +}) diff --git a/packages/plex/src/client.ts b/packages/plex/src/client.ts index 3ee0dd3..23de31b 100644 --- a/packages/plex/src/client.ts +++ b/packages/plex/src/client.ts @@ -565,8 +565,8 @@ function normaliseTrack( year: integerOrNull(item.parentYear), thumbKey: item.parentThumb ?? null, }, - genres: (item.Genre ?? []) - .map((genre) => genre.tag?.trim()) + genres: (Array.isArray(item.Genre) ? item.Genre : []) + .map((genre) => (typeof genre?.tag === 'string' ? genre.tag.trim() : undefined)) .filter((genre): genre is string => Boolean(genre)), }, ]