Skip to main content

runifold_retrieval/
error.rs

1use thiserror::Error;
2
3use crate::DocumentId;
4
5/// Failure at a provider-neutral embedding or retrieval boundary.
6#[derive(Clone, Debug, Eq, Error, PartialEq)]
7#[non_exhaustive]
8pub enum RetrievalError {
9    /// A document identity was empty.
10    #[error("document id cannot be empty")]
11    EmptyDocumentId,
12    /// A document contained no usable text.
13    #[error("document `{id}` cannot have empty text")]
14    EmptyDocumentText {
15        /// Invalid document identity.
16        id: DocumentId,
17    },
18    /// A query contained no usable text.
19    #[error("retrieval query cannot be empty")]
20    EmptyQuery,
21    /// A query requested no results.
22    #[error("retrieval limit must be greater than zero")]
23    ZeroLimit,
24    /// An embedding contained no dimensions.
25    #[error("embedding cannot be empty")]
26    EmptyEmbedding,
27    /// An embedding contained a non-finite coordinate.
28    #[error("embedding coordinate {index} must be finite")]
29    NonFiniteEmbedding {
30        /// Zero-based invalid coordinate.
31        index: usize,
32    },
33    /// An embedding coordinate exceeded a backend numeric representation.
34    #[error("embedding coordinate {index} is outside the backend numeric range")]
35    EmbeddingCoordinateOutOfRange {
36        /// Zero-based invalid coordinate.
37        index: usize,
38    },
39    /// Cosine similarity is undefined for a zero vector.
40    #[error("embedding must have a non-zero norm")]
41    ZeroNormEmbedding,
42    /// Embeddings with different dimensions cannot share an index.
43    #[error("embedding dimension mismatch: expected {expected}, received {actual}")]
44    DimensionMismatch {
45        /// Index or batch dimension.
46        expected: usize,
47        /// Received dimension.
48        actual: usize,
49    },
50    /// A provider returned a different number of vectors than inputs.
51    #[error("embedding count mismatch: expected {expected}, received {actual}")]
52    EmbeddingCountMismatch {
53        /// Input count.
54        expected: usize,
55        /// Returned vector count.
56        actual: usize,
57    },
58    /// One item in an embedding request was blank.
59    #[error("embedding input {index} cannot be empty")]
60    EmptyEmbeddingInput {
61        /// Zero-based invalid input index.
62        index: usize,
63    },
64    /// A document identity appeared more than once.
65    #[error("duplicate document id `{0}`")]
66    DuplicateDocument(DocumentId),
67    /// A run did not grant the retriever capability.
68    #[error("retriever capability `{name}` is not granted")]
69    CapabilityDenied {
70        /// Retriever name.
71        name: String,
72    },
73    /// The owning run was cancelled.
74    #[error("retrieval was cancelled")]
75    Cancelled,
76    /// The owning run deadline elapsed.
77    #[error("retrieval deadline exceeded")]
78    DeadlineExceeded,
79    /// An embedding provider or retrieval backend failed.
80    #[error("retrieval provider failed: {message}")]
81    Provider {
82        /// Safe provider diagnostic.
83        message: String,
84    },
85    /// Retrieval usage counters could not be combined without overflow.
86    #[error("retrieval usage counter overflow")]
87    UsageOverflow,
88}
89
90impl RetrievalError {
91    /// Creates a provider/backend failure without imposing an adapter error
92    /// representation.
93    pub fn provider(message: impl Into<String>) -> Self {
94        Self::Provider {
95            message: message.into(),
96        }
97    }
98}