use hyper::StatusCode;
use kellnr_http::error::ApiError;
use kellnr_storage::storage_error::StorageError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum DocsError {
#[error("Failed to extract docs")]
ExtractFailed,
#[error("Crate with version does not exist: {0}-{1}")]
CrateDoesNotExist(String, String),
#[error("Database error: {0}")]
DatabaseError(#[from] kellnr_db::error::DbError),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Cargo error: {0}")]
CargoError(String),
#[error("Docs storage error: {0}")]
StorageError(#[from] StorageError),
#[error("Archive exceeds the maximum uncompressed size or number of entries")]
ArchiveTooLarge,
#[error("Docs build timed out after {0} seconds")]
BuildTimeout(u64),
#[error("Docs build stopped on shutdown")]
BuildStopped,
#[error("Path {path} is not inside {root}")]
PathPrefixMismatch { path: String, root: String },
#[error("Failed to extract bytes from request: {0}")]
ExtractBytesFailed(#[from] axum::extract::rejection::BytesRejection),
#[error("Body of {0} bytes exceeds the maximum of {1} bytes")]
TooLarge(usize, usize),
}
impl From<DocsError> for ApiError {
fn from(e: DocsError) -> Self {
match e {
DocsError::ExtractFailed => ApiError::from_err(&e, StatusCode::INTERNAL_SERVER_ERROR),
DocsError::CrateDoesNotExist(_, _) => ApiError::from_err(&e, StatusCode::NOT_FOUND),
DocsError::DatabaseError(db_error) => ApiError::from(db_error),
DocsError::IoError(error) => ApiError::from(error),
DocsError::CargoError(error) => {
ApiError::new(&error, StatusCode::INTERNAL_SERVER_ERROR)
}
DocsError::StorageError(error) => ApiError::from(error),
DocsError::ArchiveTooLarge => ApiError::from_err(&e, StatusCode::BAD_REQUEST),
DocsError::BuildTimeout(_)
| DocsError::BuildStopped
| DocsError::PathPrefixMismatch { .. } => ApiError::internal(&e),
DocsError::ExtractBytesFailed(ref rejection) => {
let status = rejection.status();
ApiError::from_err(&e, status)
}
DocsError::TooLarge(_, _) => ApiError::from_err(&e, StatusCode::PAYLOAD_TOO_LARGE),
}
}
}