1use std::ffi::NulError;
4use std::fmt;
5use std::sync::PoisonError as StdPoisonError;
6
7pub type Result<T> = std::result::Result<T, Error>;
9
10#[derive(Debug)]
12pub enum Error {
13 ModelNotAvailable,
15
16 DeviceNotEligible,
18
19 AppleIntelligenceNotEnabled,
21
22 ModelNotReady,
24
25 InvalidInput(String),
27
28 GenerationError(String),
30
31 Timeout(String),
33
34 ToolCall(ToolCallError),
36
37 InternalError(String),
39
40 PoisonError,
42
43 Json(String),
45}
46
47#[derive(Debug, Clone)]
49pub struct ToolCallError {
50 pub tool_name: String,
52 pub arguments: serde_json::Value,
54 pub inner_error: String,
56}
57
58impl fmt::Display for Error {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 match self {
61 Error::ModelNotAvailable => {
62 write!(f, "FoundationModels is not available on this device")
63 }
64 Error::DeviceNotEligible => write!(f, "Device is not eligible for Apple Intelligence"),
65 Error::AppleIntelligenceNotEnabled => {
66 write!(f, "Apple Intelligence is not enabled in system settings")
67 }
68 Error::ModelNotReady => {
69 write!(
70 f,
71 "Model is not ready (downloading or other system reasons)"
72 )
73 }
74 Error::InvalidInput(msg) => write!(f, "Invalid input: {msg}"),
75 Error::GenerationError(msg) => write!(f, "Generation error: {msg}"),
76 Error::Timeout(msg) => write!(f, "Operation timed out: {msg}"),
77 Error::ToolCall(err) => {
78 write!(f, "Tool '{}' failed: {}", err.tool_name, err.inner_error)
79 }
80 Error::InternalError(msg) => write!(f, "Internal error: {msg}"),
81 Error::PoisonError => write!(f, "A lock was poisoned"),
82 Error::Json(msg) => write!(f, "JSON error: {msg}"),
83 }
84 }
85}
86
87impl std::error::Error for Error {
88 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
89 None
90 }
91}
92
93impl From<NulError> for Error {
94 fn from(_: NulError) -> Self {
95 Error::InvalidInput("String contains null byte".to_string())
96 }
97}
98
99impl<T> From<StdPoisonError<T>> for Error {
100 fn from(_: StdPoisonError<T>) -> Self {
101 Error::PoisonError
102 }
103}
104
105impl From<serde_json::Error> for Error {
106 fn from(err: serde_json::Error) -> Self {
107 Error::Json(err.to_string())
108 }
109}
110
111impl fmt::Display for ToolCallError {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 write!(
114 f,
115 "Tool '{}' failed with arguments {}: {}",
116 self.tool_name, self.arguments, self.inner_error
117 )
118 }
119}
120
121impl std::error::Error for ToolCallError {}