Skip to main content

orchard/
error.rs

1//! Unified error type for Orchard.
2
3use std::path::PathBuf;
4use thiserror::Error;
5
6/// Orchard error type.
7#[derive(Error, Debug)]
8pub enum Error {
9    // === IPC Errors ===
10    #[error("IPC client not connected")]
11    NotConnected,
12    #[error("Invalid response from PIE")]
13    InvalidResponse,
14    #[error("NNG error: {0}")]
15    Nng(#[from] nng::Error),
16    #[error("Request timeout")]
17    Timeout,
18    #[error("Channel closed")]
19    ChannelClosed,
20
21    // === Serialization Errors ===
22    #[error("JSON error: {0}")]
23    Json(#[from] serde_json::Error),
24    #[error("Serialization error: {0}")]
25    Serialization(String),
26    #[error("IO error: {0}")]
27    Io(#[from] std::io::Error),
28
29    // === Model Errors ===
30    #[error("Model not found: {0}")]
31    ModelNotFound(String),
32    #[error("{0}")]
33    ModelNotReady(String),
34    #[error("Model identifier cannot be empty")]
35    EmptyModelId,
36    #[error("Model directory '{0}' is missing config.json")]
37    MissingConfig(PathBuf),
38    #[error("Failed to download model '{0}': {1}")]
39    DownloadFailed(String, String),
40    #[error("Failed to initialize HuggingFace API: {0}")]
41    HfApiInit(String),
42
43    // === Formatter Errors ===
44    #[error("Formatter config not found: {0}")]
45    FormatterConfigNotFound(String),
46    #[error("Formatter profile not found: {0}")]
47    FormatterProfileNotFound(String),
48    #[error("Template error: {0}")]
49    Template(String),
50
51    // === Multimodal Errors ===
52    #[error("Invalid image data URL format")]
53    InvalidImageUrl,
54    #[error("Invalid base64-encoded image content")]
55    InvalidBase64,
56    #[error("Content part {0} in message {1} is missing a valid 'type'")]
57    MissingContentType(usize, usize),
58    #[error("Message content must be a string or list of content parts")]
59    InvalidContent,
60    #[error("Mismatch between image placeholders ({0}) and supplied images ({1})")]
61    PlaceholderMismatch(usize, usize),
62    #[error("Response request must include at least one content segment")]
63    EmptyRequest,
64
65    // === Engine Lifecycle Errors ===
66    #[error("Failed to acquire lock: {0}")]
67    LockFailed(String),
68    #[error("Engine startup failed: {0}")]
69    StartupFailed(String),
70    #[error("Engine shutdown failed: {0}")]
71    ShutdownFailed(String),
72    #[error("Engine already closed")]
73    EngineClosed,
74
75    // === Fetch Errors ===
76    #[error("HTTP error: {0}")]
77    Http(#[from] reqwest::Error),
78    #[error("Network error: {0}")]
79    Network(String),
80    #[error("Integrity check failed: expected {expected}, got {actual}")]
81    Integrity { expected: String, actual: String },
82    #[error("Invalid manifest: {0}")]
83    InvalidManifest(String),
84    #[error("No compatible binary for this platform")]
85    NoBinaryForPlatform,
86    #[error("Extract error: {0}")]
87    Extract(String),
88
89    // === Generic ===
90    #[error("{0}")]
91    Other(String),
92    #[error("Internal error: {0}")]
93    Internal(String),
94}
95
96pub type Result<T> = std::result::Result<T, Error>;