use std::fmt;
use crate::Error;
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RunErrorKind {
Parse,
Version,
Binding,
Completion,
Tool,
Store,
Lua,
Quota,
Substitution,
Cancelled,
Internal,
}
#[derive(Debug)]
#[non_exhaustive]
pub struct RunError {
inner: Error,
}
impl RunError {
#[must_use]
pub fn kind(&self) -> RunErrorKind {
match &self.inner {
Error::Parse(_) | Error::ParseStructured { .. } | Error::ParseFrontmatter { .. } => {
RunErrorKind::Parse
}
Error::LuaQuota { .. } => RunErrorKind::Quota,
Error::LuaCompile { .. } | Error::Lua(_) | Error::LuaRuntime { .. } => {
RunErrorKind::Lua
}
Error::UnsupportedVersion(_) => RunErrorKind::Version,
Error::MissingEnv(_)
| Error::InvalidEnv(_)
| Error::Config { .. }
| Error::GatewayDisabled
| Error::Http(_)
| Error::Backend { .. }
| Error::BackendBodyRead { .. }
| Error::MalformedResponse(_)
| Error::MalformedResponseSource { .. }
| Error::EmptyModelReply { .. }
| Error::DialectNone
| Error::DialectTie { .. }
| Error::UnknownDialect(_) => RunErrorKind::Completion,
Error::Interrupted => RunErrorKind::Cancelled,
Error::Substitution(_) => RunErrorKind::Substitution,
Error::ToolLoopExhausted
| Error::OutOfScopeToolCall { .. }
| Error::UnknownScopedTool(_)
| Error::Tool { .. } => RunErrorKind::Tool,
Error::FanoutArmJoin(_)
| Error::Internal(_)
| Error::InvalidToolWireName { .. }
| Error::TimestampFormat(_) => RunErrorKind::Internal,
Error::Bind { .. }
| Error::BindSchema { .. }
| Error::BindQuery { .. }
| Error::Absent { .. }
| Error::Duplicate { .. }
| Error::Ambiguous { .. }
| Error::DuplicateAlias { .. }
| Error::DuplicateLiveToolId { .. }
| Error::ToolIdSelectedTwice { .. }
| Error::PickedToolNotLive { .. }
| Error::ToolScopeAnalysis { .. }
| Error::ToolScopeAnalysisSource { .. }
| Error::NearDuplicateTools { .. }
| Error::ModelBind { .. }
| Error::ModelBindQuery { .. }
| Error::ModelAbsent { .. }
| Error::ModelDuplicate { .. }
| Error::ModelAmbiguous { .. }
| Error::DuplicateModelAlias { .. }
| Error::ModelRequired { .. } => RunErrorKind::Binding,
}
}
#[must_use]
pub fn is_cancelled(&self) -> bool {
matches!(self.inner, Error::Interrupted)
}
#[must_use]
pub fn is_retryable(&self) -> bool {
match &self.inner {
Error::Http(_)
| Error::MalformedResponse(_)
| Error::MalformedResponseSource { .. }
| Error::BackendBodyRead { .. } => true,
Error::Backend { status, .. } => *status >= 500,
_ => false,
}
}
}
impl fmt::Display for RunError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.inner)
}
}
impl std::error::Error for RunError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
std::error::Error::source(&self.inner)
}
}
impl From<Error> for RunError {
fn from(inner: Error) -> Self {
RunError { inner }
}
}
impl From<RunError> for Error {
fn from(error: RunError) -> Self {
error.inner
}
}