1
Fork 0
mirror of https://github.com/thegeneralist01/archivr synced 2026-07-22 03:05:32 +02:00

fix(frontend): prevent 'reading some of undefined' crash from stale sessionStorage

Old captureItems entries saved before the playlist fields were added
have playlistItems=undefined (missing key). The hasConflict guard
checked !== null, which undefined passes, then called .some() on
undefined → TypeError.

Two-part fix:
1. sessionStorage restore: merge each saved item over makeItem() defaults
   so any missing fields (playlistItems, playlistProbeState, etc.) are
   filled with their correct initial values before the item is used
2. hasConflict: use Array.isArray() instead of !== null so undefined
   is also safely rejected — defence-in-depth for any future field gap
This commit is contained in:
TheGeneralist 2026-07-21 12:14:44 +02:00
parent aed9c581fd
commit cca4742f89
Signed by: thegeneralist01
SSH key fingerprint: SHA256:pp9qddbCNmVNoSjevdvQvM5z0DHN7LTa8qBMbcMq/R4
3 changed files with 13 additions and 11 deletions

View file

@ -4,7 +4,7 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Archivr</title> <title>Archivr</title>
<script type="module" crossorigin src="/assets/index-DASOWXxB.js"></script> <script type="module" crossorigin src="/assets/index-DgzD6TCm.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Dd5Ih3Y1.css"> <link rel="stylesheet" crossorigin href="/assets/index-Dd5Ih3Y1.css">
</head> </head>
<body> <body>

View file

@ -151,7 +151,7 @@ function applyPlaylistQuality(newQ, currentItems) {
} }
function hasConflict(item) { function hasConflict(item) {
return item.playlistItems !== null && item.playlistItems.some(pi => pi.quality === null) return Array.isArray(item.playlistItems) && item.playlistItems.some(pi => pi.quality === null)
} }
export default function CaptureDialog({ open, archiveId, onClose, onCaptured, onToast, onJobStarted, onJobSettled, activeJobs = [] }) { export default function CaptureDialog({ open, archiveId, onClose, onCaptured, onToast, onJobStarted, onJobSettled, activeJobs = [] }) {
@ -185,7 +185,9 @@ export default function CaptureDialog({ open, archiveId, onClose, onCaptured, on
const idle = saved.filter(it => !it.status || it.status === 'idle') const idle = saved.filter(it => !it.status || it.status === 'idle')
if (idle.length > 0) { if (idle.length > 0) {
idle.forEach(it => { if (it.id >= nextItemId) nextItemId = it.id + 1 }) idle.forEach(it => { if (it.id >= nextItemId) nextItemId = it.id + 1 })
return idle // Merge with makeItem() defaults so items saved before the playlist
// fields were added don't have undefined where null/false is expected.
return idle.map(it => ({ ...makeItem(it.locator), ...it }))
} }
} }
} catch {} } catch {}