/ 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      /// Git backend error.
 26      #[error("git-http-backend: exited with code {0}")]
 27      BackendExited(ExitStatus),
 28  
 29      /// Git backend error.
 30      #[error("git-http-backend: invalid header returned: {0:?}")]
 31      BackendHeader(String),
 32  
 33      /// HeaderName error.
 34      #[error(transparent)]
 35      InvalidHeaderName(#[from] axum::http::header::InvalidHeaderName),
 36  
 37      /// HeaderValue error.
 38      #[error(transparent)]
 39      InvalidHeaderValue(#[from] axum::http::header::InvalidHeaderValue),
 40  }
 41  
 42  impl GitError {
 43      pub fn status(&self) -> http::StatusCode {
 44          match self {
 45              GitError::ServiceUnavailable(_) => http::StatusCode::SERVICE_UNAVAILABLE,
 46              GitError::Id(_) => http::StatusCode::NOT_FOUND,
 47              GitError::NotFound => http::StatusCode::NOT_FOUND,
 48              _ => http::StatusCode::INTERNAL_SERVER_ERROR,
 49          }
 50      }
 51  }
 52  
 53  impl IntoResponse for GitError {
 54      fn into_response(self) -> Response {
 55          tracing::error!("{}", self);
 56  
 57          self.status().into_response()
 58      }
 59  }
 60  
 61  /// Errors relating to the `/raw` route.
 62  #[derive(Debug, thiserror::Error)]
 63  pub enum RawError {
 64      /// Surf error.
 65      #[error(transparent)]
 66      Surf(#[from] radicle_surf::Error),
 67  
 68      /// Git error.
 69      #[error(transparent)]
 70      Git(#[from] radicle::git::ext::Error),
 71  
 72      /// Radicle Storage error.
 73      #[error(transparent)]
 74      Storage(#[from] radicle::storage::Error),
 75  
 76      /// Http Headers error.
 77      #[error(transparent)]
 78      Headers(#[from] http::header::InvalidHeaderValue),
 79  
 80      /// Surf file error.
 81      #[error(transparent)]
 82      SurfFile(#[from] radicle_surf::fs::error::File),
 83  }
 84  
 85  impl RawError {
 86      pub fn status(&self) -> http::StatusCode {
 87          match self {
 88              RawError::SurfFile(_) => http::StatusCode::NOT_FOUND,
 89              _ => http::StatusCode::INTERNAL_SERVER_ERROR,
 90          }
 91      }
 92  }
 93  
 94  impl IntoResponse for RawError {
 95      fn into_response(self) -> Response {
 96          tracing::error!("{}", self);
 97  
 98          self.status().into_response()
 99      }
100  }