fix(qt): KioskArtist threw on every mount and skipped the first cover dispatch

Found by DRIVING the app, not by the gate: opening an artist logged
"TypeError: Cannot read property 'length' of undefined" at KioskArtist.qml:106
on every mount. The view still rendered, which is why nothing else caught it.

collectArtwork() read root.sections -- a readonly property derived from
`artist` -- from inside onArtistChanged, which is connected to the very notify
that dirties it. The handler runs BEFORE the dependent binding re-evaluates,
so the read saw undefined. Main.qml:233-247 already documents this hazard and
its remedy from the window-geometry work: compute from the value at call time,
never read a cached derived property inside its own handler.

Cost of the bug: the first artwork dispatch for an artist page was skipped
entirely, so covers only arrived if a later pass happened to re-request them.

Verified BY EFFECT -- rebuilt, re-drove to the artist page over VNC, and the
run log is now clean -- not by re-reading the diff.

cc
This commit is contained in:
vicrodh committed 2026-08-03 23:43:01 -06:00
1 parent 63e36c7543
commit ea26d743ab
1 file changed
+15 -4
+15 -4
View File
@@ -99,12 +99,23 @@ Flickable {
// The portrait plus every section's cards — INCLUDING the sections this
// view does not render, because a later publish pass can fill one and make
// it renderable, and nothing downstream reports a url that was never sent.
// Reads `artist` and derives the sections HERE rather than reading the
// `sections` property, and that is load-bearing. `onArtistChanged` below
// is connected to the very notify that dirties `sections`, and the handler
// runs BEFORE the dependent binding is re-evaluated — so a read of
// `root.sections` from inside it saw `undefined` and threw
// `Cannot read property 'length' of undefined` on every mount, skipping
// the first artwork dispatch. Same hazard, same remedy, as the note at
// Main.qml:233-247: compute from the value at call time instead of reading
// a cached derived property.
function collectArtwork() {
var urls = []
if (root.artist && root.artist.artUrl)
urls.push(root.artist.artUrl)
for (var s = 0; s < root.sections.length; s++) {
var cards = root.sections[s].cards || []
var a = root.artist
if (a && a.artUrl)
urls.push(a.artUrl)
var sections = (a && a.releaseSections) ? a.releaseSections : []
for (var s = 0; s < sections.length; s++) {
var cards = sections[s].cards || []
for (var c = 0; c < cards.length; c++)
if (cards[c].artUrl)
urls.push(cards[c].artUrl)