Skip to main content

htsget_axum/
error.rs

1//! This module contains error and result types for htsget-axum.
2//!
3
4use axum::response::{IntoResponse, Response};
5use axum_extra::response::ErasedJson;
6use std::net::AddrParseError;
7use std::{io, result};
8use thiserror::Error;
9
10/// The result type for htsget-axum.
11pub type Result<T> = result::Result<T, Error>;
12
13/// The error type for htsget-axum
14#[derive(Error, Debug)]
15pub enum Error {
16  #[error("{0}")]
17  IoError(#[from] io::Error),
18
19  #[error("server error: {0}")]
20  ServerError(String),
21
22  #[error("invalid address: {0}")]
23  InvalidAddress(#[from] AddrParseError),
24
25  #[error("building auth middleware: {0}")]
26  AuthBuilderError(String),
27}
28
29impl From<hyper::Error> for Error {
30  fn from(error: hyper::Error) -> Self {
31    Self::ServerError(error.to_string())
32  }
33}
34
35impl From<Error> for io::Error {
36  fn from(error: Error) -> Self {
37    if let Error::IoError(io) = error {
38      io
39    } else {
40      io::Error::other(error)
41    }
42  }
43}
44
45impl From<htsget_http::middleware::error::Error> for Error {
46  fn from(error: htsget_http::middleware::error::Error) -> Self {
47    Self::AuthBuilderError(error.to_string())
48  }
49}
50
51/// The result type for htsget errors.
52pub type HtsGetResult<T> = result::Result<T, HtsGetError>;
53
54/// A wrapper around the http HtsGetError for implementing Axum response traits.
55#[derive(Debug)]
56pub struct HtsGetError(pub htsget_http::HtsGetError);
57
58impl HtsGetError {
59  /// Create a permission denied error.
60  pub fn permission_denied(err: String) -> HtsGetError {
61    htsget_http::HtsGetError::PermissionDenied(err).into()
62  }
63
64  /// Create an invalid authentication error.
65  pub fn invalid_authentication(err: String) -> HtsGetError {
66    htsget_http::HtsGetError::InvalidAuthentication(err).into()
67  }
68
69  /// Create a not found error.
70  pub fn not_found(err: String) -> HtsGetError {
71    htsget_http::HtsGetError::NotFound(err).into()
72  }
73
74  /// Create a payload too large error.
75  pub fn payload_too_large(err: String) -> HtsGetError {
76    htsget_http::HtsGetError::PayloadTooLarge(err).into()
77  }
78
79  /// Create an unsupported format error.
80  pub fn unsupported_format(err: String) -> HtsGetError {
81    htsget_http::HtsGetError::UnsupportedFormat(err).into()
82  }
83
84  /// Create an invalid input error.
85  pub fn invalid_input(err: String) -> HtsGetError {
86    htsget_http::HtsGetError::InvalidInput(err).into()
87  }
88
89  /// Create an invalid range error.
90  pub fn invalid_range(err: String) -> HtsGetError {
91    htsget_http::HtsGetError::InvalidRange(err).into()
92  }
93
94  /// Create a method not allowed error.
95  pub fn method_not_allowed(err: String) -> HtsGetError {
96    htsget_http::HtsGetError::MethodNotAllowed(err).into()
97  }
98
99  /// Create an internal error.
100  pub fn internal_error(err: String) -> HtsGetError {
101    htsget_http::HtsGetError::InternalError(err).into()
102  }
103}
104
105impl IntoResponse for HtsGetError {
106  fn into_response(self) -> Response {
107    let (json, status_code) = self.0.to_json_representation();
108    (status_code, ErasedJson::pretty(json)).into_response()
109  }
110}
111
112impl From<htsget_http::HtsGetError> for HtsGetError {
113  fn from(err: htsget_http::HtsGetError) -> Self {
114    Self(err)
115  }
116}
117
118impl From<jsonwebtoken::errors::Error> for HtsGetError {
119  fn from(err: jsonwebtoken::errors::Error) -> Self {
120    Self::invalid_authentication(format!("invalid JWT: {err}"))
121  }
122}