From 783ea99bd0488dbf71a21d2ae03bec09ac651860 Mon Sep 17 00:00:00 2001 From: pewdiepie-archdaemon Date: Mon, 29 Jun 2026 12:27:56 +0000 Subject: [PATCH] Show cached model scan failures --- routes/cookbook_routes.py | 15 ++++++++++++--- static/js/cookbook-hwfit.js | 8 ++++++-- static/js/cookbookServe.js | 11 +++++++++-- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/routes/cookbook_routes.py b/routes/cookbook_routes.py index 437747220..f95cdcea6 100644 --- a/routes/cookbook_routes.py +++ b/routes/cookbook_routes.py @@ -932,10 +932,16 @@ def setup_cookbook_routes() -> APIRouter: cwd=str(Path.home()), ) stdout_b, stderr_b = await asyncio.wait_for(proc.communicate(), timeout=60) + stderr_txt = stderr_b.decode(errors="replace").strip() + stdout_txt = stdout_b.decode(errors="replace").strip() + if proc.returncode != 0: + msg = stderr_txt or f"Cached model scan failed with exit code {proc.returncode}" + logger.warning(f"Cached model scan failed host={host or 'local'} rc={proc.returncode}: {msg[:500]}") + return {"models": [], "host": host or "local", "error": msg} models = [] try: - raw = json.loads(stdout_b.decode(errors="replace").strip()) + raw = json.loads(stdout_txt) for m in raw: size_gb = m["size_bytes"] / (1024 ** 3) if size_gb >= 1: @@ -963,8 +969,11 @@ def setup_cookbook_routes() -> APIRouter: entry["gguf_files"] = m["gguf_files"] models.append(entry) except Exception as e: - logger.warning(f"Failed to parse cached models: {e}") - logger.warning(f"stderr: {stderr_b.decode(errors='replace')[:500]}") + logger.warning(f"Failed to parse cached models host={host or 'local'}: {e}") + if stderr_txt: + logger.warning(f"stderr: {stderr_txt[:500]}") + msg = stderr_txt or stdout_txt[:500] or str(e) + return {"models": [], "host": host or "local", "error": msg} return {"models": models, "host": host or "local"} diff --git a/static/js/cookbook-hwfit.js b/static/js/cookbook-hwfit.js index 0ff6654f6..2bc34fc54 100644 --- a/static/js/cookbook-hwfit.js +++ b/static/js/cookbook-hwfit.js @@ -625,7 +625,6 @@ export async function _hwfitFetch(fresh = false, opts = {}) { // Only fetch cached model IDs when server changes, not on every search/sort const remoteKey = _currentServerValue(); if (!_cachedModelIds || _lastCacheHost() !== remoteKey) { - _setLastCacheHost(remoteKey); const _cacheSrv = _serverByVal(_envState.remoteServerKey || remoteHost); const _cachePort = _cacheSrv?.port || ''; const _cacheParams = new URLSearchParams(); @@ -637,9 +636,11 @@ export async function _hwfitFetch(fresh = false, opts = {}) { fetch(`/api/model/cached?${_cacheParams}`, { credentials: 'same-origin' }) .then(r => r.json()) .then(d => { + if (d && d.error) throw new Error(d.error); // Exclude stalled (download-shell) entries — a 12 KB README-only // folder shouldn't count as "downloaded" in the Scan/Download list. _cachedModelIds = new Set((d.models || []).filter(m => m.status !== 'stalled').map(m => m.repo_id)); + _setLastCacheHost(remoteKey); // Re-mark rows if already rendered list.querySelectorAll('.hwfit-row[data-model]').forEach(row => { const name = row.dataset.model; @@ -650,7 +651,10 @@ export async function _hwfitFetch(fresh = false, opts = {}) { } } }); - }).catch(() => {}); + }).catch((err) => { + console.warn('Cached model marker scan failed:', err); + _setLastCacheHost(''); + }); } if (_paintedFromCache) { try { wp.destroy(); } catch {} diff --git a/static/js/cookbookServe.js b/static/js/cookbookServe.js index 3938d73b4..d026c1e5b 100644 --- a/static/js/cookbookServe.js +++ b/static/js/cookbookServe.js @@ -3657,7 +3657,10 @@ function _renderCachedModelsData(list, data, host) { if (!host) { list.innerHTML = '
No cached models found
Docker Local uses Odysseus’s cache in data/huggingface. Download a model here, or copy an existing host HuggingFace cache into that folder once.
'; } else { - list.innerHTML = '
No cached models found
'; + list.innerHTML = '
No cached models found
No complete model folders were found on this server.
'; + list.querySelector('.serve-empty-scan-btn')?.addEventListener('click', () => { + _fetchCachedModels(true); + }); } const tagContainer = document.getElementById('serve-tags'); if (tagContainer) tagContainer.innerHTML = ''; @@ -3822,12 +3825,16 @@ export async function _fetchCachedModels(fresh = false, opts = {}) { throw new Error(`HTTP ${res.status} ${res.statusText}${msg ? `: ${msg}` : ''}`); } const data = await res.json(); + if (data && data.error) throw new Error(data.error); _writeCachedModelScan(scanSig, data); _dlWp.destroy(); _renderCachedModelsData(list, data, host); } catch (e) { _dlWp.destroy(); - list.innerHTML = `
Failed: ${esc(e.message)}
`; + list.innerHTML = `
Cached model scan failed
${esc(e.message)}
`; + list.querySelector('.serve-empty-scan-btn')?.addEventListener('click', () => { + _fetchCachedModels(true); + }); } }