zeph_index/error.rs
1// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Error types for `zeph-index`.
5//!
6//! All fallible operations in this crate return [`Result<T>`], which is an alias for
7//! `std::result::Result<T, IndexError>`. Each variant wraps the upstream error type with
8//! an `#[from]` impl so callers can propagate errors with `?` without manual conversion.
9
10use std::num::TryFromIntError;
11
12#[non_exhaustive]
13/// Errors that can occur during code indexing operations.
14///
15/// # Examples
16///
17/// ```
18/// use zeph_index::error::{IndexError, Result};
19///
20/// fn must_succeed() -> Result<()> {
21/// Err(IndexError::UnsupportedLanguage)
22/// }
23///
24/// assert!(matches!(must_succeed(), Err(IndexError::UnsupportedLanguage)));
25/// ```
26#[derive(Debug, thiserror::Error)]
27pub enum IndexError {
28 /// I/O error reading source files from disk.
29 ///
30 /// Raised when [`tokio::fs::read_to_string`] or [`std::fs::read_to_string`] fail,
31 /// for example because a file was deleted between discovery and indexing.
32 #[error("I/O error: {0}")]
33 Io(#[from] std::io::Error),
34
35 /// `SQLite` database error from `sqlx`.
36 ///
37 /// Raised by metadata reads/writes in [`crate::store::CodeStore`].
38 #[error("sqlx error: {0}")]
39 Sqlite(#[from] zeph_db::SqlxError),
40
41 /// Qdrant vector store error.
42 ///
43 /// Raised by upsert, search, or collection management operations in
44 /// [`crate::store::CodeStore`].
45 #[error("vector store error: {0}")]
46 VectorStore(#[from] zeph_memory::VectorStoreError),
47
48 /// LLM provider error during embedding.
49 ///
50 /// Raised when the configured embedding provider returns an error, for example
51 /// due to a network timeout or an unsupported model name.
52 #[error("LLM error: {0}")]
53 Llm(#[from] zeph_llm::LlmError),
54
55 /// JSON serialization or deserialization error.
56 ///
57 /// Raised when Qdrant payload values cannot be serialized or when point
58 /// payloads contain unexpected types.
59 #[error("JSON error: {0}")]
60 Json(#[from] serde_json::Error),
61
62 /// Tree-sitter parsing error.
63 ///
64 /// Raised when a grammar is unavailable for a language, or when tree-sitter
65 /// fails to produce a parse tree (rare — tree-sitter is error-tolerant).
66 ///
67 /// The inner `String` contains a human-readable description of the failure.
68 #[error("parse failed: {0}")]
69 Parse(String),
70
71 /// Unsupported or unrecognized language.
72 ///
73 /// Raised by [`crate::indexer`] when a file has a recognized extension but no
74 /// corresponding tree-sitter grammar is available for it.
75 #[error("unsupported language")]
76 UnsupportedLanguage,
77
78 /// Filesystem watcher initialization error.
79 ///
80 /// Raised by [`crate::watcher::IndexWatcher::start`] when the underlying
81 /// `notify` watcher cannot be created or the root path cannot be watched.
82 #[error("watcher error: {0}")]
83 Watcher(#[from] notify::Error),
84
85 /// Integer conversion error when mapping `usize` values to `i64` or `u64`.
86 ///
87 /// Raised when line numbers or chunk counts overflow the target integer type,
88 /// which in practice only occurs on pathological inputs.
89 #[error("integer conversion failed: {0}")]
90 IntConversion(#[from] TryFromIntError),
91
92 /// Embedding call timed out.
93 ///
94 /// Raised by [`crate::retriever::CodeRetriever`] and
95 /// [`crate::indexer::CodeIndexer`] when `provider.embed()` does not complete
96 /// within the configured timeout.
97 #[error("embedding timed out after {0}s")]
98 EmbedTimeout(u64),
99
100 /// Generic catch-all error for cases that do not fit the variants above.
101 ///
102 /// Used internally for errors like a panicking background thread (e.g., the
103 /// directory walk `spawn_blocking` task).
104 #[error("{0}")]
105 Other(String),
106}
107
108/// Result type alias using [`IndexError`].
109///
110/// Returned by all fallible public functions in `zeph-index`.
111///
112/// # Examples
113///
114/// ```
115/// use zeph_index::error::{IndexError, Result};
116///
117/// fn parse_something(ok: bool) -> Result<u32> {
118/// if ok { Ok(42) } else { Err(IndexError::UnsupportedLanguage) }
119/// }
120/// ```
121pub type Result<T> = std::result::Result<T, IndexError>;