1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use std::fmt;
/// Typed build and query failures.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum SearchError {
/// The supplied [`crate::IndexConfig`] cannot construct a valid index.
InvalidConfig(&'static str),
/// A vector or query did not match the configured dimensionality.
DimensionMismatch {
/// Required number of components.
expected: usize,
/// Observed number of components.
actual: usize,
/// Input-vector position, or `None` when validating a query.
vector: Option<usize>,
},
/// A vector or query component was NaN or infinite.
NonFiniteValue {
/// Input-vector position, or `None` when validating a query.
vector: Option<usize>,
/// Position of the invalid component.
dimension: usize,
},
/// A stored vector or query had zero magnitude.
ZeroVector {
/// Input-vector position, or `None` when validating a query.
vector: Option<usize>,
},
/// More than one stored vector used the same caller-provided key.
DuplicateKey(u64),
/// More than one vector used the same key and per-key vector identifier.
DuplicateVectorId { key: u64, vector_id: u64 },
/// Index sizes or degree arithmetic exceeded supported capacity.
CapacityOverflow,
/// A fallible reservation for index or query storage failed.
AllocationFailed,
/// A bounded build or query worker panicked.
WorkerPanic,
/// A filesystem operation failed while reading or writing an index.
Storage {
/// Operation that failed.
operation: &'static str,
/// Portable operating-system error category.
kind: std::io::ErrorKind,
},
/// A persisted index failed structural or integrity validation.
CorruptSnapshot(&'static str),
/// The snapshot format is newer or older than this crate understands.
UnsupportedSnapshotVersion(u32),
/// A requested vector key was not present.
MissingKey(u64),
/// An embedding provider rejected an input or failed to produce a vector.
EmbeddingFailed(String),
/// A local or remote search shard failed.
ShardFailed {
/// Stable zero-based shard position.
shard: usize,
/// Provider-specific failure text.
message: String,
},
/// Mutations changed while an optimistic compaction was being built.
MutationConflict,
}
impl SearchError {
pub(crate) fn storage(operation: &'static str, error: &std::io::Error) -> Self {
Self::Storage {
operation,
kind: error.kind(),
}
}
}
impl fmt::Display for SearchError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidConfig(message) => write!(formatter, "invalid index config: {message}"),
Self::DimensionMismatch {
expected,
actual,
vector,
} => match vector {
Some(vector) => write!(
formatter,
"vector {vector} has {actual} dimensions; expected {expected}"
),
None => write!(
formatter,
"query has {actual} dimensions; expected {expected}"
),
},
Self::NonFiniteValue { vector, dimension } => match vector {
Some(vector) => {
write!(
formatter,
"vector {vector} has a non-finite value at dimension {dimension}"
)
}
None => write!(
formatter,
"query has a non-finite value at dimension {dimension}"
),
},
Self::ZeroVector {
vector: Some(vector),
} => {
write!(formatter, "vector {vector} has zero magnitude")
}
Self::ZeroVector { vector: None } => formatter.write_str("query has zero magnitude"),
Self::DuplicateKey(key) => write!(formatter, "duplicate vector key {key}"),
Self::DuplicateVectorId { key, vector_id } => {
write!(formatter, "duplicate vector id {vector_id} for key {key}")
}
Self::CapacityOverflow => formatter.write_str("index capacity arithmetic overflowed"),
Self::AllocationFailed => formatter.write_str("index allocation failed"),
Self::WorkerPanic => formatter.write_str("a bounded vector-search worker panicked"),
Self::Storage { operation, kind } => {
write!(
formatter,
"index storage operation {operation} failed: {kind}"
)
}
Self::CorruptSnapshot(message) => {
write!(formatter, "corrupt vector-index snapshot: {message}")
}
Self::UnsupportedSnapshotVersion(version) => {
write!(
formatter,
"unsupported vector-index snapshot version {version}"
)
}
Self::MissingKey(key) => write!(formatter, "vector key {key} was not found"),
Self::EmbeddingFailed(message) => {
write!(formatter, "embedding provider failed: {message}")
}
Self::ShardFailed { shard, message } => {
write!(formatter, "vector-search shard {shard} failed: {message}")
}
Self::MutationConflict => {
formatter.write_str("mutable index changed repeatedly during compaction")
}
}
}
}
impl std::error::Error for SearchError {}