oxibonsai_runtime/
error.rs1use oxibonsai_core::error::BonsaiError;
4use oxibonsai_kernels::error::KernelError;
5use oxibonsai_model::error::ModelError;
6
7#[derive(Debug, thiserror::Error)]
9pub enum RuntimeError {
10 #[error("core error: {0}")]
11 Core(#[from] BonsaiError),
12
13 #[error("kernel error: {0}")]
14 Kernel(#[from] KernelError),
15
16 #[error("model error: {0}")]
17 Model(#[from] ModelError),
18
19 #[error("tokenizer error: {0}")]
20 Tokenizer(String),
21
22 #[error("generation stopped: {reason}")]
23 GenerationStopped { reason: String },
24
25 #[error("server error: {0}")]
26 Server(String),
27
28 #[error("GGUF file not found: {path}")]
29 FileNotFound { path: String },
30
31 #[error("IO error: {0}")]
32 Io(#[from] std::io::Error),
33
34 #[error("configuration error: {0}")]
35 Config(String),
36
37 #[error("operation timed out: {operation} after {duration_ms}ms")]
38 Timeout {
39 operation: String,
41 duration_ms: u64,
43 },
44
45 #[error("circuit breaker is open, requests are being rejected")]
46 CircuitOpen,
47
48 #[error("capacity exhausted: {resource}")]
49 CapacityExhausted {
50 resource: String,
52 },
53
54 #[error("batch error: {} sub-errors", .0.len())]
55 BatchError(Vec<RuntimeError>),
56}
57
58impl RuntimeError {
59 pub fn error_code(&self) -> &str {
61 match self {
62 Self::Core(_) => "CORE_ERROR",
63 Self::Kernel(_) => "KERNEL_ERROR",
64 Self::Model(_) => "MODEL_ERROR",
65 Self::Tokenizer(_) => "TOKENIZER_ERROR",
66 Self::GenerationStopped { .. } => "GENERATION_STOPPED",
67 Self::Server(_) => "SERVER_ERROR",
68 Self::FileNotFound { .. } => "FILE_NOT_FOUND",
69 Self::Io(_) => "IO_ERROR",
70 Self::Config(_) => "CONFIG_ERROR",
71 Self::Timeout { .. } => "TIMEOUT",
72 Self::CircuitOpen => "CIRCUIT_OPEN",
73 Self::CapacityExhausted { .. } => "CAPACITY_EXHAUSTED",
74 Self::BatchError(_) => "BATCH_ERROR",
75 }
76 }
77
78 pub fn is_retryable(&self) -> bool {
80 match self {
81 Self::Io(_) => true,
82 Self::Timeout { .. } => true,
83 Self::Server(_) => true,
84 Self::CircuitOpen => true,
85 Self::CapacityExhausted { .. } => true,
86 Self::BatchError(errors) => errors.iter().any(|e| e.is_retryable()),
87 _ => false,
88 }
89 }
90}
91
92pub type RuntimeResult<T> = Result<T, RuntimeError>;