Files
iptvnator/libs/shared/interfaces/src/lib/playlist-auto-update.interface.ts
T
4grayandClaude Opus 5 f852bc7459 fix(playlists): report failed playlists in the startup auto-refresh toast (#1235)
The startup auto-refresh always opened the
`HOME.PLAYLISTS.AUTO_REFRESH_UPDATE_SUCCESS` snackbar, even when the backend
had dropped playlists it could not refresh. Isolating per-playlist failures
(#1233) means the result set is lossy by design, so an unreachable source that
now fails within `PLAYLIST_FETCH_TIMEOUT_MS` produces a false success toast.

`autoUpdatePlaylists()` now returns `AutoUpdatePlaylistsResult` — the refreshed
playlists plus one outcome per requested playlist (`updated` / `failed` /
`skipped`), in request order — on top of the existing bounded-concurrency
refresh. The renderer derives the message from those outcomes:

- all updated -> `AUTO_REFRESH_UPDATE_SUCCESS` (unchanged)
- some failed -> `AUTO_REFRESH_UPDATE_PARTIAL` (error styling, dismissable)
- some failed and some skipped -> `AUTO_REFRESH_UPDATE_PARTIAL_WITH_SKIPPED`
- none updated -> `AUTO_REFRESH_UPDATE_FAILED` (error styling, dismissable)
- only sourceless playlists left over -> `AUTO_REFRESH_UPDATE_SKIPPED`

Playlists with neither a URL nor a file path are reported as skipped rather
than failed, since there is no source to refresh them from. The mixed
failed+skipped message exists because the plain partial text names only
updated/total/failed, which would leave the skipped playlists as an
unexplained remainder. Titles of unresolved playlists are logged for
diagnosability.

Tests: five new `electron.service` cases (one per message branch), outcome
assertions across the existing `playlist-auto-update` and `playlist.events`
specs, and an Electron E2E that restarts the app against a killed playlist
server — verified to fail against the old unconditional toast.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 11:33:07 +02:00

46 lines
1.4 KiB
TypeScript

import { Playlist } from './playlist.interface';
/**
* Result of a single playlist inside a startup auto-refresh run.
*
* - `updated`: the playlist source was fetched/read and parsed successfully
* - `failed`: the source could not be reached, read or parsed
* - `skipped`: the playlist has neither a URL nor a file path, so there is
* nothing to refresh from (a configuration problem, not a failure)
*/
export type AutoUpdatePlaylistStatus = 'updated' | 'failed' | 'skipped';
export interface AutoUpdatePlaylistOutcome {
playlistId: string;
title: string;
status: AutoUpdatePlaylistStatus;
}
export interface AutoUpdatePlaylistsResult {
/** Only the playlists that were refreshed successfully. */
playlists: Playlist[];
/** One entry per requested playlist, in request order. */
outcomes: AutoUpdatePlaylistOutcome[];
}
export interface AutoUpdatePlaylistsSummary {
total: number;
updated: number;
failed: number;
skipped: number;
}
export function summarizeAutoUpdateOutcomes(
outcomes: readonly AutoUpdatePlaylistOutcome[]
): AutoUpdatePlaylistsSummary {
return {
total: outcomes.length,
updated: outcomes.filter((outcome) => outcome.status === 'updated')
.length,
failed: outcomes.filter((outcome) => outcome.status === 'failed')
.length,
skipped: outcomes.filter((outcome) => outcome.status === 'skipped')
.length,
};
}