use reqwest::{Method, StatusCode};
use std::num::TryFromIntError;
use thiserror::Error;
#[non_exhaustive]
#[derive(Debug, Error)]
pub enum Error {
#[error("invalid configuration: {0}")]
Config(String),
#[error("invalid HTTP header value")]
Header(#[from] reqwest::header::InvalidHeaderValue),
#[error("HTTP transport error on {method} {endpoint}")]
Transport {
method: Method,
endpoint: String,
#[source]
source: reqwest::Error,
},
#[error("MarpleDB API returned {status} on {method} {endpoint}: {body}")]
Api {
method: Method,
endpoint: String,
status: StatusCode,
body: String,
},
#[error("storage transfer failed: {context}")]
Storage {
context: String,
status: Option<StatusCode>,
body: Option<String>,
#[source]
source: Option<reqwest::Error>,
},
#[error("stream {name:?} not found")]
StreamNotFound {
name: String,
},
#[error("stream {id} not found")]
StreamIdNotFound {
id: i32,
},
#[error("dataset {id} has no backup available")]
NoBackup {
id: i32,
},
#[error("ingestion timed out after {timeout_secs}s, last status: {last_status}")]
ImportTimeout {
timeout_secs: u64,
last_status: String,
},
#[error("ingestion failed for dataset {id}: {message}")]
ImportFailed {
id: i32,
message: String,
},
#[error("invalid server response: {0}")]
Protocol(String),
#[error("I/O error")]
Io(#[from] std::io::Error),
#[error("URL parse error")]
Url(#[from] url::ParseError),
#[error("JSON error")]
Json(#[from] serde_json::Error),
#[error("integer conversion failed")]
IntegerConversion(#[from] TryFromIntError),
}
impl Error {
pub fn status(&self) -> Option<StatusCode> {
match self {
Self::Api { status, .. } => Some(*status),
Self::Storage { status, .. } => *status,
_ => None,
}
}
}
pub type Result<T> = std::result::Result<T, Error>;