Skip to main content

uni_xervo/
error.rs

1//! Error types for the Uni-Xervo runtime.
2
3use crate::traits::{DimSize, TensorDtype};
4use std::path::PathBuf;
5use thiserror::Error;
6
7/// Convenience alias used throughout the crate.
8pub type Result<T> = std::result::Result<T, RuntimeError>;
9
10/// Unified error type covering configuration, loading, inference, and transport
11/// failures.
12///
13/// Variants are intentionally coarse-grained so that callers can match on error
14/// *category* (e.g. retryable vs permanent) rather than on provider-specific
15/// details.
16#[derive(Debug, Error)]
17pub enum RuntimeError {
18    /// Invalid or missing configuration (bad alias format, unknown option, etc.).
19    #[error("Configuration error: {0}")]
20    Config(String),
21
22    /// The requested alias does not exist in the runtime catalog.
23    #[error("Alias not found: {alias}")]
24    AliasNotFound { alias: String },
25
26    /// The requested provider ID is not registered with the runtime.
27    #[error("Provider not found: {0}")]
28    ProviderNotFound(String),
29
30    /// A model was requested for a task the provider does not support.
31    #[error("Capability mismatch: {0}")]
32    CapabilityMismatch(String),
33
34    /// The resolved provider does not expose the requested runtime capability.
35    #[error(
36        "Provider capability missing for alias '{alias}' (provider '{provider_id}'): {capability}"
37    )]
38    ProviderCapabilityMissing {
39        alias: String,
40        provider_id: String,
41        capability: String,
42    },
43
44    /// Model loading or initialization failed (download, weight parsing, etc.).
45    #[error("Load error: {0}")]
46    Load(String),
47
48    /// An HTTP or transport-level error from a remote provider.
49    #[error("API error: {0}")]
50    ApiError(String),
51
52    /// An error during model inference (tokenization, forward pass, etc.).
53    #[error("Inference error: {0}")]
54    InferenceError(String),
55
56    #[error("ONNX model not found for alias '{alias}': {path}")]
57    OnnxModelNotFound { alias: String, path: PathBuf },
58
59    #[error("ONNX artifact selection failure for alias '{alias}': {cause}")]
60    OnnxArtifactSelectionFailure { alias: String, cause: String },
61
62    #[error("ONNX download failure for alias '{alias}': {cause}")]
63    OnnxDownloadFailure { alias: String, cause: String },
64
65    #[error("ONNX load failure for alias '{alias}' at '{path}': {cause}")]
66    OnnxLoadFailure {
67        alias: String,
68        path: PathBuf,
69        cause: String,
70    },
71
72    #[error("ONNX signature introspection failure for alias '{alias}': {cause}")]
73    OnnxSignatureIntrospectionFailure { alias: String, cause: String },
74
75    #[error("ONNX input missing for alias '{alias}': required input '{required_input}'")]
76    OnnxInputMissing {
77        alias: String,
78        required_input: String,
79    },
80
81    #[error(
82        "ONNX input type mismatch for alias '{alias}', input '{input_name}': expected {expected:?}, got {got:?}"
83    )]
84    OnnxInputTypeMismatch {
85        alias: String,
86        input_name: String,
87        expected: TensorDtype,
88        got: TensorDtype,
89    },
90
91    #[error(
92        "ONNX input shape mismatch for alias '{alias}', input '{input_name}': expected {expected:?}, got {got:?}"
93    )]
94    OnnxInputShapeMismatch {
95        alias: String,
96        input_name: String,
97        expected: Vec<DimSize>,
98        got: Vec<usize>,
99    },
100
101    #[error("ONNX invocation failure for alias '{alias}': {cause}")]
102    OnnxInvocationFailure { alias: String, cause: String },
103
104    #[error("ONNX batch stacking failure for alias '{alias}': {cause}")]
105    OnnxBatchStackingFailure { alias: String, cause: String },
106
107    /// The remote API returned HTTP 429 (too many requests).
108    #[error("Rate limited")]
109    RateLimited,
110
111    /// The remote API returned HTTP 401/403 (bad or missing credentials).
112    #[error("Unauthorized")]
113    Unauthorized,
114
115    /// The operation exceeded its configured timeout.
116    #[error("Timeout")]
117    Timeout,
118
119    /// The service is currently unavailable (HTTP 5xx, circuit breaker open, etc.).
120    #[error("Unavailable")]
121    Unavailable,
122}
123
124impl RuntimeError {
125    /// Returns `true` for transient errors that may succeed on retry:
126    /// [`RateLimited`](Self::RateLimited), [`Timeout`](Self::Timeout), and
127    /// [`Unavailable`](Self::Unavailable).
128    pub fn is_retryable(&self) -> bool {
129        matches!(self, Self::RateLimited | Self::Timeout | Self::Unavailable)
130    }
131}