This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knot2 / crates / knot-pack / src / error.rs
3.1 kB 90 lines
1use std::fmt; 2 3use axum::http::StatusCode; 4use axum::response::{IntoResponse, Response}; 5 6#[derive(Debug, Clone, Copy, PartialEq, Eq)] 7pub enum PackLimit { 8 Objects, 9 ObjectBytes, 10 TotalBytes, 11 DeltaDepth, 12} 13 14impl fmt::Display for PackLimit { 15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 16 f.write_str(match self { 17 PackLimit::Objects => "object count", 18 PackLimit::ObjectBytes => "per-object size", 19 PackLimit::TotalBytes => "total decompressed size", 20 PackLimit::DeltaDepth => "delta chain depth", 21 }) 22 } 23} 24 25#[derive(Debug, thiserror::Error)] 26pub enum PackError { 27 #[error("repository not found")] 28 NotFound, 29 #[error("repository index is warming, retry shortly")] 30 Unavailable, 31 #[error("invalid request path: {0}")] 32 BadPath(String), 33 #[error("unsupported service")] 34 UnsupportedService, 35 #[error("push is served over SSH, not HTTP")] 36 PushOverSsh, 37 #[error("protocol: {0}")] 38 Protocol(String), 39 #[error("unsupported request content-encoding: {0}")] 40 UnsupportedEncoding(String), 41 #[error("pkt-line: {0}")] 42 PktLine(#[from] std::io::Error), 43 #[error("pack: {0}")] 44 Pack(String), 45 #[error("pack exceeds {0} limit")] 46 LimitExceeded(PackLimit), 47 #[error("upload-pack selection exceeded its object-set limit")] 48 SelectionTooLarge, 49 #[error("upload-pack selection exceeded its time budget")] 50 SelectionTimeout, 51 #[error("insufficient memory to ingest this push, retry when the server is less busy")] 52 InsufficientMemory, 53 #[error(transparent)] 54 Git(knot_git::GitError), 55} 56 57impl From<knot_git::GitError> for PackError { 58 fn from(error: knot_git::GitError) -> Self { 59 use knot_git::SelectionLimit; 60 match error { 61 knot_git::GitError::Selection(SelectionLimit::Objects) => PackError::SelectionTooLarge, 62 knot_git::GitError::Selection(SelectionLimit::Time) => PackError::SelectionTimeout, 63 other => PackError::Git(other), 64 } 65 } 66} 67 68impl PackError { 69 pub fn http_status(&self) -> StatusCode { 70 match self { 71 PackError::NotFound => StatusCode::NOT_FOUND, 72 PackError::Unavailable => StatusCode::SERVICE_UNAVAILABLE, 73 PackError::PushOverSsh => StatusCode::FORBIDDEN, 74 PackError::BadPath(_) | PackError::UnsupportedService => StatusCode::BAD_REQUEST, 75 PackError::Protocol(_) | PackError::PktLine(_) => StatusCode::BAD_REQUEST, 76 PackError::UnsupportedEncoding(_) => StatusCode::UNSUPPORTED_MEDIA_TYPE, 77 PackError::LimitExceeded(_) => StatusCode::PAYLOAD_TOO_LARGE, 78 PackError::SelectionTooLarge 79 | PackError::SelectionTimeout 80 | PackError::InsufficientMemory => StatusCode::SERVICE_UNAVAILABLE, 81 PackError::Pack(_) | PackError::Git(_) => StatusCode::INTERNAL_SERVER_ERROR, 82 } 83 } 84} 85 86impl IntoResponse for PackError { 87 fn into_response(self) -> Response { 88 (self.http_status(), self.to_string()).into_response() 89 } 90}