use std::path::PathBuf;
use dvm_api::{CommandNumber, RunId, RunState, SandboxId};
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("400: {reason}")]
InvalidRequest { reason: String },
#[error("401: {reason}")]
Authentication { reason: String },
#[error("404: {reason}")]
NotFound { reason: String },
#[error("409: {reason}")]
Conflict { reason: String },
#[error("{status}: {reason}")]
Refused { status: u16, reason: String },
#[error("sandbox {sandbox} is {}", state.kind())]
SandboxEnded { sandbox: SandboxId, state: RunState },
#[error("sandbox {sandbox} failed: {reason}")]
SandboxFailed { sandbox: SandboxId, reason: String },
#[error("command {number} was refused: {reason}")]
CommandRefused {
number: CommandNumber,
reason: String,
},
#[error("replay {replay} {}{}", state.kind(), failure_of(state))]
ReplayEnded { replay: RunId, state: RunState },
#[error("no API key for {api_url}: run `dvm-run login`, or set DVM_API_KEY")]
NoApiKey { api_url: String },
#[error("{}: {problem}", path.display())]
Credentials { path: PathBuf, problem: String },
#[error("{context}")]
Network {
context: String,
#[source]
source: Option<reqwest::Error>,
},
#[error("{0}")]
Unexpected(String),
}
impl Error {
pub(crate) fn refusal(status: u16, reason: String) -> Self {
match status {
400 => Self::InvalidRequest { reason },
401 => Self::Authentication { reason },
404 => Self::NotFound { reason },
409 => Self::Conflict { reason },
status => Self::Refused { status, reason },
}
}
pub(crate) fn ended(sandbox: SandboxId, state: RunState) -> Self {
match state {
RunState::Failed { reason } => Self::SandboxFailed { sandbox, reason },
state => Self::SandboxEnded { sandbox, state },
}
}
pub(crate) fn network(context: impl Into<String>, source: reqwest::Error) -> Self {
Self::Network {
context: context.into(),
source: Some(source),
}
}
}
fn failure_of(state: &RunState) -> String {
match state {
RunState::Failed { reason } => format!(": {reason}"),
_ => String::new(),
}
}