From e401cb5f486ab4c9dad72da699c056027a561265 Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Mon, 4 May 2026 18:02:36 -0700 Subject: [PATCH] fix(web): error handling in LibraryView, taskId watch in IngestProgress, type fixes --- web/src/api.ts | 7 +++++- web/src/components/DocumentCard.vue | 2 +- web/src/components/IngestProgress.vue | 19 +++++++++++---- web/src/views/LibraryView.vue | 34 +++++++++++++++++++++++---- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/web/src/api.ts b/web/src/api.ts index e4e960b..37daf48 100644 --- a/web/src/api.ts +++ b/web/src/api.ts @@ -36,6 +36,11 @@ export interface TaskStatus { error?: string } +export interface ChatMessage { + role: string + content: string +} + export const api = { async getLibrary(): Promise { const r = await fetch(`${BASE}/api/library`) @@ -72,7 +77,7 @@ export const api = { }, async chat( message: string, - history: { role: string; content: string }[], + history: ChatMessage[], docIds?: string[], topK = 5, ): Promise { diff --git a/web/src/components/DocumentCard.vue b/web/src/components/DocumentCard.vue index d3ebbb9..eac1de3 100644 --- a/web/src/components/DocumentCard.vue +++ b/web/src/components/DocumentCard.vue @@ -2,7 +2,7 @@
{{ doc.status }}
{{ doc.title }}
-
{{ doc.page_count }} pages
+
{{ doc.page_count }} pages
{{ shortPath }}
diff --git a/web/src/views/LibraryView.vue b/web/src/views/LibraryView.vue index c27a5d4..9972e0a 100644 --- a/web/src/views/LibraryView.vue +++ b/web/src/views/LibraryView.vue @@ -7,6 +7,8 @@ +

{{ error }}

+

No books indexed yet. Click "Scan for PDFs" to discover PDFs in your books directory.
Make sure your PDF directory is mounted at /books inside the container. @@ -37,32 +39,53 @@ import DocumentCard from "@/components/DocumentCard.vue" const docs = ref([]) const loading = ref(true) const scanning = ref(false) +const error = ref(null) const scanResult = ref<{ discovered: number; queued: number } | null>(null) async function load() { loading.value = true - docs.value = await api.getLibrary().finally(() => (loading.value = false)) + error.value = null + try { + docs.value = await api.getLibrary() + } catch (e) { + error.value = e instanceof Error ? e.message : "Failed to load library" + } finally { + loading.value = false + } } async function scan() { scanning.value = true + error.value = null try { scanResult.value = await api.scanLibrary() await load() + } catch (e) { + error.value = e instanceof Error ? e.message : "Scan failed" } finally { scanning.value = false } } async function reingest(id: string) { - await api.reingestDocument(id) - await load() + error.value = null + try { + await api.reingestDocument(id) + await load() + } catch (e) { + error.value = e instanceof Error ? e.message : "Re-index failed" + } } async function remove(id: string) { if (!confirm("Remove this book from the library? The PDF file is not deleted.")) return - await api.deleteDocument(id) - await load() + error.value = null + try { + await api.deleteDocument(id) + await load() + } catch (e) { + error.value = e instanceof Error ? e.message : "Remove failed" + } } onMounted(load) @@ -81,4 +104,5 @@ h1 { font-size: 1.5rem; } .empty-state { color: var(--color-text-muted); line-height: 1.8; } .empty-state code { font-family: var(--font-mono); background: var(--color-surface-alt); padding: 2px 6px; border-radius: 3px; } .scan-result { margin-top: 1rem; color: var(--color-text-muted); font-size: 0.9rem; } +.error-msg { color: var(--color-error); margin-bottom: 1rem; font-size: 0.9rem; }