/ radicle-httpd / src / error.rs
error.rs
  1  use std::process::ExitStatus;
  2  
  3  use axum::http;
  4  use axum::response::{IntoResponse, Response};
  5  
  6  /// Errors relating to the Git backend.
  7  #[derive(Debug, thiserror::Error)]
  8  pub enum GitError {
  9      /// The entity was not found.
 10      #[error("not found")]
 11      NotFound,
 12  
 13      /// I/O error.
 14      #[error("i/o error: {0}")]
 15      Io(#[from] std::io::Error),
 16  
 17      /// The service is not available.
 18      #[error("service '{0}' not available")]
 19      ServiceUnavailable(&'static str),
 20  
 21      /// Invalid identifier.
 22      #[error("invalid radicle identifier: {0}")]
 23      Id(#[from] radicle::identity::IdError),
 24  
 25      /// Storage error.
 26      #[error("storage: {0}")]
 27      Storage(#[from] radicle::storage::Error),
 28  
 29      /// Repository error.
 30      #[error("repository: {0}")]
 31      Repository(#[from] radicle::storage::RepositoryError),
 32  
 33      /// Git backend error.
 34      #[error("git-http-backend: exited with code {0}")]
 35      BackendExited(ExitStatus),
 36  
 37      /// Git backend error.
 38      #[error("git-http-backend: invalid header returned: {0:?}")]
 39      BackendHeader(String),
 40  
 41      /// HeaderName error.
 42      #[error(transparent)]
 43      InvalidHeaderName(#[from] axum::http::header::InvalidHeaderName),
 44  
 45      /// HeaderValue error.
 46      #[error(transparent)]
 47      InvalidHeaderValue(#[from] axum::http::header::InvalidHeaderValue),
 48  }
 49  
 50  impl GitError {
 51      pub fn status(&self) -> http::StatusCode {
 52          match self {
 53              GitError::ServiceUnavailable(_) => http::StatusCode::SERVICE_UNAVAILABLE,
 54              GitError::Id(_) => http::StatusCode::NOT_FOUND,
 55              GitError::NotFound => http::StatusCode::NOT_FOUND,
 56              _ => http::StatusCode::INTERNAL_SERVER_ERROR,
 57          }
 58      }
 59  }
 60  
 61  impl IntoResponse for GitError {
 62      fn into_response(self) -> Response {
 63          tracing::error!("{}", self);
 64  
 65          self.status().into_response()
 66      }
 67  }
 68  
 69  /// Errors relating to the `/raw` route.
 70  #[derive(Debug, thiserror::Error)]
 71  pub enum RawError {
 72      /// Surf error.
 73      #[error(transparent)]
 74      Surf(#[from] radicle_surf::Error),
 75  
 76      /// Git2 error.
 77      #[error(transparent)]
 78      Git2(#[from] radicle::git::raw::Error),
 79  
 80      /// Payload error.
 81      #[error(transparent)]
 82      ProjectPayload(#[from] radicle::identity::PayloadError),
 83  
 84      /// Io error.
 85      #[error(transparent)]
 86      Io(#[from] std::io::Error),
 87  
 88      /// Archive error.
 89      #[error("`git archive` exited with status {0}:\n{1}")]
 90      Archive(ExitStatus, String),
 91  
 92      /// Git error.
 93      #[error(transparent)]
 94      Git(#[from] radicle::git::ext::Error),
 95  
 96      /// Radicle Storage error.
 97      #[error(transparent)]
 98      Storage(#[from] radicle::storage::Error),
 99  
100      /// Repository error.
101      #[error(transparent)]
102      Repository(#[from] radicle::storage::RepositoryError),
103  
104      /// Http Headers error.
105      #[error(transparent)]
106      Headers(#[from] http::header::InvalidHeaderValue),
107  
108      /// Surf file error.
109      #[error(transparent)]
110      SurfFile(#[from] radicle_surf::fs::error::File),
111  
112      /// The entity was not found.
113      #[error("not found")]
114      NotFound,
115  }
116  
117  impl RawError {
118      pub fn status(&self) -> http::StatusCode {
119          match self {
120              RawError::SurfFile(_) | RawError::NotFound => http::StatusCode::NOT_FOUND,
121              _ => http::StatusCode::INTERNAL_SERVER_ERROR,
122          }
123      }
124  }
125  
126  impl IntoResponse for RawError {
127      fn into_response(self) -> Response {
128          tracing::error!("{}", self);
129  
130          self.status().into_response()
131      }
132  }