mod embedding;
mod kind;
mod model;
mod parse;
mod tool;
mod vectorstore;
pub use embedding::EmbeddingError;
pub use kind::SynwireErrorKind;
pub use model::ModelError;
pub use parse::ParseError;
pub use tool::ToolError;
pub use vectorstore::VectorStoreError;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum SynwireError {
#[error(transparent)]
Model(#[from] ModelError),
#[error("prompt error: {message}")]
Prompt {
message: String,
},
#[error(transparent)]
Parse(#[from] ParseError),
#[error(transparent)]
Embedding(#[from] EmbeddingError),
#[error(transparent)]
VectorStore(#[from] VectorStoreError),
#[error(transparent)]
Tool(#[from] ToolError),
#[error("serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("graph error: {0}")]
Graph(Box<dyn std::error::Error + Send + Sync>),
#[error("credential error: {message}")]
Credential {
message: String,
},
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Other(Box<dyn std::error::Error + Send + Sync>),
}
impl SynwireError {
pub const fn kind(&self) -> SynwireErrorKind {
match self {
Self::Model(_) => SynwireErrorKind::Model,
Self::Prompt { .. } => SynwireErrorKind::Prompt,
Self::Parse(_) => SynwireErrorKind::Parse,
Self::Embedding(_) => SynwireErrorKind::Embedding,
Self::VectorStore(_) => SynwireErrorKind::VectorStore,
Self::Tool(_) => SynwireErrorKind::Tool,
Self::Serialization(_) => SynwireErrorKind::Serialization,
Self::Graph(_) => SynwireErrorKind::Graph,
Self::Credential { .. } => SynwireErrorKind::Credential,
Self::Io(_) | Self::Other(_) => SynwireErrorKind::Other,
}
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn test_error_display_model() {
let err = SynwireError::from(ModelError::Timeout);
assert!(err.to_string().contains("timed out"));
}
#[test]
fn test_error_display_prompt() {
let err = SynwireError::Prompt {
message: "missing variable 'name'".into(),
};
assert!(err.to_string().contains("missing variable"));
}
#[test]
fn test_error_from_model_error() {
let model_err = ModelError::RateLimit { retry_after: None };
let err: SynwireError = model_err.into();
assert_eq!(err.kind(), SynwireErrorKind::Model);
}
#[test]
fn test_error_from_tool_error() {
let tool_err = ToolError::NotFound {
name: "search".into(),
};
let err: SynwireError = tool_err.into();
assert_eq!(err.kind(), SynwireErrorKind::Tool);
}
#[test]
fn test_error_kind_matching() {
let err = SynwireError::from(ParseError::ParseFailed {
message: "bad json".into(),
});
assert_eq!(err.kind(), SynwireErrorKind::Parse);
}
}