vss_client/
error.rs

1use crate::types::{ErrorCode, ErrorResponse};
2use prost::bytes::Bytes;
3use prost::{DecodeError, Message};
4use reqwest::StatusCode;
5use std::error::Error;
6use std::fmt::{Display, Formatter};
7
8/// When there is an error while writing to VSS storage, the response contains a relevant error code.
9/// A mapping from a VSS server error codes. Refer to [`ErrorResponse`] docs for more
10/// information regarding each error code and corresponding use-cases.
11#[derive(Debug)]
12pub enum VssError {
13	/// Please refer to [`ErrorCode::NoSuchKeyException`].
14	NoSuchKeyError(String),
15
16	/// Please refer to [`ErrorCode::InvalidRequestException`].
17	InvalidRequestError(String),
18
19	/// Please refer to [`ErrorCode::ConflictException`].
20	ConflictError(String),
21
22	/// Please refer to [`ErrorCode::AuthException`].
23	AuthError(String),
24
25	/// Please refer to [`ErrorCode::InternalServerException`].
26	InternalServerError(String),
27
28	/// There is an unknown error, it could be a client-side bug, unrecognized error-code, network error
29	/// or something else.
30	InternalError(String),
31}
32
33impl VssError {
34	/// Create new instance of `VssError`
35	pub fn new(status: StatusCode, payload: Bytes) -> VssError {
36		match ErrorResponse::decode(&payload[..]) {
37			Ok(error_response) => VssError::from(error_response),
38			Err(e) => {
39				let message = format!(
40					"Unable to decode ErrorResponse from server, HttpStatusCode: {}, DecodeErr: {}",
41					status, e
42				);
43				VssError::InternalError(message)
44			},
45		}
46	}
47}
48
49impl Display for VssError {
50	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
51		match self {
52			VssError::NoSuchKeyError(message) => {
53				write!(f, "Requested key does not exist: {}", message)
54			},
55			VssError::InvalidRequestError(message) => {
56				write!(f, "Request sent to VSS Storage was invalid: {}", message)
57			},
58			VssError::ConflictError(message) => {
59				write!(f, "Potential version conflict in write operation: {}", message)
60			},
61			VssError::AuthError(message) => {
62				write!(f, "Authentication or Authorization failure: {}", message)
63			},
64			VssError::InternalServerError(message) => {
65				write!(f, "InternalServerError: {}", message)
66			},
67			VssError::InternalError(message) => {
68				write!(f, "InternalError: {}", message)
69			},
70		}
71	}
72}
73
74impl Error for VssError {}
75
76impl From<ErrorResponse> for VssError {
77	fn from(error_response: ErrorResponse) -> Self {
78		match error_response.error_code() {
79			ErrorCode::NoSuchKeyException => VssError::NoSuchKeyError(error_response.message),
80			ErrorCode::InvalidRequestException => {
81				VssError::InvalidRequestError(error_response.message)
82			},
83			ErrorCode::ConflictException => VssError::ConflictError(error_response.message),
84			ErrorCode::AuthException => VssError::AuthError(error_response.message),
85			ErrorCode::InternalServerException => {
86				VssError::InternalServerError(error_response.message)
87			},
88			_ => VssError::InternalError(format!(
89				"VSS responded with an unknown error code: {}, message: {}",
90				error_response.error_code, error_response.message
91			)),
92		}
93	}
94}
95
96impl From<DecodeError> for VssError {
97	fn from(err: DecodeError) -> Self {
98		VssError::InternalError(err.to_string())
99	}
100}
101
102impl From<reqwest::Error> for VssError {
103	fn from(err: reqwest::Error) -> Self {
104		VssError::InternalError(err.to_string())
105	}
106}