Skip to main content

post_cortex_embeddings/
error.rs

1// Copyright (c) 2025, 2026 Julius ML
2// Licensed under the MIT License. See LICENSE at the workspace root.
3
4//! Typed error hierarchy for `post-cortex-embeddings`.
5//!
6//! Public API on this crate returns [`Result<T>`] (aliased to
7//! `Result<T, Error>`). Internal helpers may still use `anyhow::Result`
8//! for ergonomic error context — the boundary functions wrap them with
9//! [`Error::External`].
10//!
11//! Variants:
12//! - [`Error::ModelLoad`] — failed to download or open the safetensors
13//!   model file (hf-hub network / disk / format issues).
14//! - [`Error::Tokenization`] — tokenizer JSON parse failure or
15//!   encoding mismatch.
16//! - [`Error::Inference`] — candle tensor op error during the forward
17//!   pass.
18//! - [`Error::Dimension`] — embedding dimension mismatch when an
19//!   external vector is fed into the wrong index.
20//! - [`Error::IndexFull`] — HNSW index reached its configured capacity.
21//! - [`Error::External`] — last-resort wrapper around `anyhow::Error`
22//!   for migrating call sites.
23
24use thiserror::Error;
25
26/// Errors produced by [`crate`].
27#[derive(Debug, Error)]
28pub enum Error {
29    /// Failed to load the embedding model file (network / disk / format).
30    #[error("embedding model load failed: {0}")]
31    ModelLoad(String),
32
33    /// Tokeniser failed to parse its config or encode the input string.
34    #[error("tokenization failed: {0}")]
35    Tokenization(String),
36
37    /// Forward pass returned a candle / tensor error.
38    #[error("inference failed: {0}")]
39    Inference(String),
40
41    /// Caller supplied a vector with a dimension other than the
42    /// index's expected width.
43    #[error("vector dimension mismatch: expected {expected}, got {actual}")]
44    Dimension {
45        /// Dimension the index was built with.
46        expected: usize,
47        /// Dimension of the supplied vector.
48        actual: usize,
49    },
50
51    /// HNSW index is full.
52    #[error("vector index is full")]
53    IndexFull,
54
55    /// Catch-all for migrating call sites that still use `anyhow`.
56    #[error(transparent)]
57    External(#[from] anyhow::Error),
58}
59
60/// Crate-level result alias.
61pub type Result<T, E = Error> = std::result::Result<T, E>;
62
63impl Error {
64    /// A stable discriminant for metrics / structured logs.
65    #[must_use]
66    pub fn kind(&self) -> &'static str {
67        match self {
68            Self::ModelLoad(_) => "model_load",
69            Self::Tokenization(_) => "tokenization",
70            Self::Inference(_) => "inference",
71            Self::Dimension { .. } => "dimension_mismatch",
72            Self::IndexFull => "index_full",
73            Self::External(_) => "external",
74        }
75    }
76}