Skip to main content

vision_calibration_pipeline/
error.rs

1//! Typed error hierarchy for `vision-calibration-pipeline`.
2
3use vision_calibration_core::Error as CoreError;
4use vision_calibration_linear::Error as LinearError;
5use vision_calibration_optim::Error as OptimError;
6
7/// Errors returned by `vision-calibration-pipeline` public APIs.
8#[derive(Debug, thiserror::Error)]
9#[non_exhaustive]
10pub enum Error {
11    /// An argument violates a documented precondition.
12    #[error("invalid input: {reason}")]
13    InvalidInput { reason: String },
14
15    /// Not enough observations to proceed.
16    #[error("insufficient data: need {need}, got {got}")]
17    InsufficientData { need: usize, got: usize },
18
19    /// A required resource (input, state, output) was not yet set in the session.
20    #[error("session resource not available: {resource}")]
21    NotAvailable { resource: &'static str },
22
23    /// A numerical failure (singular matrix, divergence, etc.).
24    #[error("numerical failure: {0}")]
25    Numerical(String),
26
27    /// Error propagated from a JSON serialization/deserialization step.
28    #[error("serialization error: {0}")]
29    Serde(#[from] serde_json::Error),
30
31    /// Error propagated from the core crate.
32    #[error(transparent)]
33    Core(#[from] CoreError),
34
35    /// Error propagated from the linear crate.
36    #[error(transparent)]
37    Linear(#[from] LinearError),
38
39    /// Error propagated from the optim crate.
40    #[error(transparent)]
41    Optim(#[from] OptimError),
42}
43
44impl Error {
45    /// Construct an [`Error::InvalidInput`] with the given reason.
46    pub(crate) fn invalid_input(reason: impl Into<String>) -> Self {
47        Self::InvalidInput {
48            reason: reason.into(),
49        }
50    }
51
52    /// Construct an [`Error::Numerical`] with the given message.
53    pub(crate) fn numerical(msg: impl Into<String>) -> Self {
54        Self::Numerical(msg.into())
55    }
56
57    /// Construct an [`Error::NotAvailable`] for a named resource.
58    pub(crate) fn not_available(resource: &'static str) -> Self {
59        Self::NotAvailable { resource }
60    }
61}
62
63/// Allow `anyhow::Error` to be converted to a pipeline `Error` (catches any
64/// internal `anyhow`-style failures at the session boundary).
65impl From<anyhow::Error> for Error {
66    fn from(e: anyhow::Error) -> Self {
67        Self::Numerical(e.to_string())
68    }
69}