@@ -51,9 +51,10 @@ type updateAvailableMsg struct {
5151}
5252
5353type scanDoneMsg struct {
54- pkgs []model.Package
55- err error
56- fromCache bool
54+ pkgs []model.Package
55+ err error
56+ fromCache bool
57+ failedManagers []string // names of managers whose Scan() returned an error
5758}
5859
5960// scanStartMsg announces how many managers will be scanned concurrently.
@@ -301,7 +302,7 @@ type Model struct {
301302 scanCompleted int
302303 scanAccum []model.Package
303304 scanCurrentMgr string
304- scanErrored bool
305+ scanFailed [] string // sources whose Scan() errored during the current pass
305306
306307 // Title intro animation. `titleReveal` is the number of characters of
307308 // "GlazePKG" currently visible; tea.Tick increments it on mount until
@@ -825,32 +826,31 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
825826 m .scanTotal = msg .total
826827 m .scanCompleted = 0
827828 m .scanAccum = m .scanAccum [:0 ]
829+ m .scanFailed = m .scanFailed [:0 ]
828830 m .scanCurrentMgr = ""
829- m .scanErrored = false
830831 return m , tea .Batch (cmds ... )
831832
832833 case scanManagerDoneMsg :
833834 if msg .err != nil {
834- m .scanErrored = true
835+ m .scanFailed = append ( m . scanFailed , string ( msg . source ))
835836 } else {
836837 m .scanAccum = append (m .scanAccum , msg .pkgs ... )
837838 }
838839 m .scanCompleted ++
839840 m .scanCurrentMgr = string (msg .source )
840841 if m .scanCompleted >= m .scanTotal {
841842 pkgs := m .scanAccum
843+ failed := append ([]string (nil ), m .scanFailed ... )
842844 m .scanAccum = nil
843- errored := m .scanErrored
844845 return m , func () tea.Msg {
845846 sort .Slice (pkgs , func (i , j int ) bool { return pkgs [i ].Name < pkgs [j ].Name })
846- // Only persist the cache when every manager scanned cleanly.
847- // Otherwise a transient failure would be frozen into the
848- // cache and the missing packages would stay invisible until
849- // the user forces a rescan.
850- if ! errored {
851- manager .SaveScanCache (pkgs )
852- }
853- return scanDoneMsg {pkgs : pkgs }
847+ // Save whatever succeeded. Consistently-broken managers
848+ // (e.g. bun with no globals always exits 1) must not be
849+ // able to veto caching the other 9 managers' data —
850+ // otherwise the cache goes stale forever and the user
851+ // sees a permanent "loaded from cache (Nh old)" message.
852+ manager .SaveScanCache (pkgs )
853+ return scanDoneMsg {pkgs : pkgs , failedManagers : failed }
854854 }
855855 }
856856 return m , nil
@@ -881,9 +881,15 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
881881 }
882882 m .tabs = buildTabs (m .allPkgs )
883883 m .applyFilter ()
884- if msg .fromCache {
884+ switch {
885+ case msg .fromCache :
885886 age := manager .ScanCacheAge ()
886887 m .statusMsg = fmt .Sprintf ("loaded from cache (%s old) — press r to rescan" , formatDuration (age ))
888+ case len (msg .failedManagers ) > 0 :
889+ m .statusMsg = fmt .Sprintf ("rescan complete — %d packages (%s scan failed)" ,
890+ len (msg .pkgs ), strings .Join (msg .failedManagers , ", " ))
891+ default :
892+ m .statusMsg = fmt .Sprintf ("rescan complete — %d packages" , len (msg .pkgs ))
887893 }
888894 // Dispatch background description fetch (skip packages with user notes)
889895 m .loadingDescs = true
0 commit comments