1use htsget_config::types::HtsGetError as HtsGetSearchError;
2use http::StatusCode;
3use http::header::{InvalidHeaderName, InvalidHeaderValue};
4use serde::{Deserialize, Serialize};
5use thiserror::Error;
6
7pub type Result<T> = core::result::Result<T, HtsGetError>;
8
9#[derive(Error, Debug, PartialEq, Eq)]
12pub enum HtsGetError {
13 #[error("InvalidAuthentication")]
14 InvalidAuthentication(String),
15 #[error("PermissionDenied")]
16 PermissionDenied(String),
17 #[error("NotFound")]
18 NotFound(String),
19 #[error("PayloadTooLarge")]
20 PayloadTooLarge(String),
21 #[error("UnsupportedFormat")]
22 UnsupportedFormat(String),
23 #[error("InvalidInput")]
24 InvalidInput(String),
25 #[error("InvalidRange")]
26 InvalidRange(String),
27 #[error("MethodNotAllowed")]
28 MethodNotAllowed(String),
29 #[error("InternalError")]
30 InternalError(String),
31 #[error("Wrapped")]
32 Wrapped(WrappedHtsGetError, StatusCode),
33}
34
35#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
38pub struct JsonHtsGetError {
39 error: String,
40 message: String,
41}
42
43#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
45pub struct WrappedHtsGetError {
46 htsget: JsonHtsGetError,
47}
48
49impl HtsGetError {
50 pub fn to_json_representation(&self) -> (WrappedHtsGetError, StatusCode) {
53 let (err, status_code) = match self {
54 HtsGetError::InvalidAuthentication(err) => (err, StatusCode::UNAUTHORIZED),
55 HtsGetError::PermissionDenied(err) => (err, StatusCode::FORBIDDEN),
56 HtsGetError::NotFound(err) => (err, StatusCode::NOT_FOUND),
57 HtsGetError::PayloadTooLarge(err) => (err, StatusCode::PAYLOAD_TOO_LARGE),
58 HtsGetError::UnsupportedFormat(err)
59 | HtsGetError::InvalidInput(err)
60 | HtsGetError::InvalidRange(err) => (err, StatusCode::BAD_REQUEST),
61 HtsGetError::MethodNotAllowed(err) => (err, StatusCode::METHOD_NOT_ALLOWED),
62 HtsGetError::InternalError(err) => (err, StatusCode::INTERNAL_SERVER_ERROR),
63 HtsGetError::Wrapped(err, status) => return (err.clone(), *status),
64 };
65
66 (
67 WrappedHtsGetError {
68 htsget: JsonHtsGetError {
69 error: self.to_string(),
70 message: err.to_string(),
71 },
72 },
73 status_code,
74 )
75 }
76}
77
78impl From<HtsGetSearchError> for HtsGetError {
79 fn from(error: HtsGetSearchError) -> Self {
80 match error {
81 HtsGetSearchError::NotFound(err) => Self::NotFound(err),
82 HtsGetSearchError::UnsupportedFormat(err) => Self::UnsupportedFormat(err),
83 HtsGetSearchError::InvalidInput(err) => Self::InvalidInput(err),
84 HtsGetSearchError::InvalidRange(err) => Self::InvalidRange(err),
85 HtsGetSearchError::IoError(err) | HtsGetSearchError::ParseError(err) => Self::NotFound(err),
86 HtsGetSearchError::InternalError(err) => Self::InternalError(err),
87 }
88 }
89}
90
91impl From<InvalidHeaderName> for HtsGetError {
92 fn from(err: InvalidHeaderName) -> Self {
93 Self::InternalError(err.to_string())
94 }
95}
96
97impl From<InvalidHeaderValue> for HtsGetError {
98 fn from(err: InvalidHeaderValue) -> Self {
99 Self::InternalError(err.to_string())
100 }
101}
102
103impl From<reqwest_middleware::Error> for HtsGetError {
104 fn from(err: reqwest_middleware::Error) -> Self {
105 match err {
106 reqwest_middleware::Error::Middleware(err) => HtsGetError::InternalError(err.to_string()),
107 reqwest_middleware::Error::Reqwest(err) => err
108 .status()
109 .map(|status| match status {
110 StatusCode::UNAUTHORIZED => HtsGetError::InvalidAuthentication(err.to_string()),
111 StatusCode::FORBIDDEN => HtsGetError::PermissionDenied(err.to_string()),
112 StatusCode::NOT_FOUND => HtsGetError::NotFound(err.to_string()),
113 StatusCode::PAYLOAD_TOO_LARGE => HtsGetError::PayloadTooLarge(err.to_string()),
114 StatusCode::BAD_REQUEST => HtsGetError::InvalidInput(err.to_string()),
115 StatusCode::METHOD_NOT_ALLOWED => HtsGetError::MethodNotAllowed(err.to_string()),
116 _ => HtsGetError::InternalError(err.to_string()),
117 })
118 .unwrap_or(HtsGetError::InternalError(err.to_string())),
119 }
120 }
121}