use std::error::Error;
use std::fmt;
use crate::cm_types::LLM_CANCELLED_ERROR;
use super::call_error::LlmCallError;
#[derive(Debug)]
pub enum LlmCompleteError {
Cancelled,
Transport(LlmCallError),
Other(Box<dyn Error + Send + Sync>),
}
impl fmt::Display for LlmCompleteError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Cancelled => f.write_str(LLM_CANCELLED_ERROR),
Self::Transport(e) => f.write_str(&e.user_message),
Self::Other(e) => fmt::Display::fmt(e, f),
}
}
}
impl Error for LlmCompleteError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Cancelled => None,
Self::Transport(e) => Some(e),
Self::Other(e) => Some(e.as_ref()),
}
}
}
impl LlmCompleteError {
pub fn from_boxed(e: Box<dyn Error + Send + Sync>) -> Self {
if e.to_string().trim() == LLM_CANCELLED_ERROR {
return Self::Cancelled;
}
if let Some(llm) = e.downcast_ref::<LlmCallError>() {
return Self::Transport(llm.clone());
}
Self::Other(e)
}
pub fn retryable(&self) -> bool {
match self {
Self::Cancelled => false,
Self::Transport(e) => e.retryable,
Self::Other(_) => false,
}
}
pub fn http_status(&self) -> Option<u16> {
match self {
Self::Cancelled => None,
Self::Transport(e) => e.http_status,
Self::Other(_) => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cancelled_string_matches_constant() {
assert_eq!(LlmCompleteError::Cancelled.to_string(), LLM_CANCELLED_ERROR);
}
}