Skip to main content

semantic_operators/
error.rs

1//! Structured errors without automatic inclusion of request data.
2use std::fmt;
3/// Classification of a library failure.
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5pub enum ErrorKind {
6    /// Invalid question definition.
7    InvalidQuestion,
8    /// Invalid argument.
9    InvalidArgument,
10    /// Invalid state shape.
11    InvalidState,
12    /// Invalid image.
13    InvalidImage,
14    /// Invalid wire request.
15    InvalidRequest,
16    /// Malformed provider output.
17    InvalidResponse,
18    /// Provider or transport failure.
19    Provider,
20    /// Deadline expired.
21    Timeout,
22    /// Unsupported capability.
23    Unsupported,
24    /// Runtime misuse or interrupted local execution.
25    Runtime,
26}
27/// A classified error with an optional field path.
28#[derive(Clone, Debug, PartialEq, Eq)]
29pub struct Error {
30    kind: ErrorKind,
31    message: String,
32    path: Option<String>,
33}
34impl Error {
35    /// Construct an error. Messages should not contain secrets or private state.
36    pub fn new(kind: ErrorKind, message: impl Into<String>) -> Self {
37        Self {
38            kind,
39            message: message.into(),
40            path: None,
41        }
42    }
43    /// Attach a schema field path.
44    pub fn with_path(mut self, path: impl Into<String>) -> Self {
45        self.path = Some(path.into());
46        self
47    }
48    /// Error classification.
49    pub fn kind(&self) -> ErrorKind {
50        self.kind
51    }
52    /// Safe diagnostic message, excluding the field path.
53    pub fn message(&self) -> &str {
54        &self.message
55    }
56    /// Optional schema field path.
57    pub fn path(&self) -> Option<&str> {
58        self.path.as_deref()
59    }
60}
61impl fmt::Display for Error {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        if let Some(p) = self.path.as_ref().filter(|p| !p.is_empty()) {
64            write!(f, "{p}: ")?;
65        }
66        f.write_str(&self.message)
67    }
68}
69impl std::error::Error for Error {}