vaas/
error.rs

1//! The `Error` type is returned by the `vaas` API everywhere, where an error can occur.
2
3use crate::message::{ErrorResponse, VerdictResponse};
4use reqwest::StatusCode;
5use std::sync::PoisonError;
6use thiserror::Error;
7use tokio::sync::broadcast::error::SendError;
8use tokio::sync::oneshot::error::RecvError;
9use tokio::time::error::Elapsed;
10use websockets::WebSocketError;
11
12/// VaaS Result type.
13pub type VResult<T> = Result<T, Error>;
14
15/// `Error` is the only error type in the `vaas` API.
16#[non_exhaustive]
17#[derive(Error, Debug, Clone)]
18pub enum Error {
19    /// A websocket error occurred.
20    #[error("WebSocket Error: `{0}`")]
21    WebSocket(String),
22    /// A serialization or deserialization error occurred.
23    #[error("Serialization Error: `{0}`")]
24    DeSerialization(String),
25    /// Failed to acquire the message lock.
26    #[error("Cannot acquire message lock: `{0}`")]
27    Lock(String),
28    /// Received an invalid verdict type.
29    #[error("Received an invalid verdict type: `{0}`")]
30    InvalidVerdict(String),
31    /// Request was cancelled due to a timeout.
32    #[error("Request was cancelled")]
33    Cancelled,
34    /// Received an invalid frame from the websocket.
35    #[error("Invalid frame received")]
36    InvalidFrame,
37    /// Received an invalid message from the endpoint.
38    #[error("Invalid message received: `{0}`")]
39    InvalidMessage(String),
40    /// No connection was established between the client and server. Did you forget to call `connect()`?
41    #[error("No connection established. Did you forget to connect?")]
42    NoConnection,
43    /// The upload URL is not set but expected to be.
44    #[error("Upload URL not set but expected")]
45    NoUploadUrl,
46    /// A generic IO error occurred.
47    #[error("IO Error: `{0}`")]
48    IoError(String),
49    /// The provided string is not a valid SHA256.
50    #[error("Invalid SHA256: `{0}`")]
51    InvalidSha256(String),
52    /// Failed create a request to upload a file.
53    #[error("Failed to send file: `{0}`")]
54    FailedRequest(String),
55    /// Failed to upload the file. Server answered with an non-200 status code.
56    #[error("Server answered with status code: `{0}` `{1}`")]
57    FailedUploadFile(StatusCode, String),
58    /// Authentication token for the file upload in the response message is missing.
59    #[error("Missing authentication token for file upload")]
60    MissingAuthToken,
61    /// Unauthorized
62    #[error("Unauthorized: `{0}`")]
63    Unauthorized(String),
64    /// Broadcast send/receive error between threads occurred.
65    #[error("The result channel failed: `{0}`")]
66    ResultChannelError(String),
67    /// Server returned an error.
68    #[error("Error response from the server")]
69    ErrorResponse(ErrorResponse),
70    /// Failed to get authentication token from the OpenID provider.
71    #[error("Failed to get authentication token. Status code `{0}` with message `{1}`")]
72    FailedAuthTokenRequest(StatusCode, String),
73    /// For an successful authentication response, a session id has to be send by the server.
74    /// If no session id is send, but the response has the success flag that, this error is used.
75    #[error("No session id in authentication response set")]
76    NoSessionIdInAuthResp,
77    /// Connection was closed, reconnect is necessary
78    #[error("Connection was closed")]
79    ConnectionClosed,
80}
81
82impl From<PoisonError<std::sync::MutexGuard<'_, websockets::WebSocketWriteHalf>>> for Error {
83    fn from(e: PoisonError<std::sync::MutexGuard<'_, websockets::WebSocketWriteHalf>>) -> Self {
84        Self::Lock(e.to_string())
85    }
86}
87
88impl From<WebSocketError> for Error {
89    fn from(e: WebSocketError) -> Self {
90        Self::WebSocket(e.to_string())
91    }
92}
93
94impl From<serde_json::Error> for Error {
95    fn from(e: serde_json::Error) -> Self {
96        Self::DeSerialization(e.to_string())
97    }
98}
99
100impl From<std::io::Error> for Error {
101    fn from(e: std::io::Error) -> Self {
102        Self::IoError(e.to_string())
103    }
104}
105
106impl From<reqwest::Error> for Error {
107    fn from(e: reqwest::Error) -> Self {
108        Self::FailedRequest(e.to_string())
109    }
110}
111
112impl From<tokio::sync::broadcast::error::SendError<Result<VerdictResponse, Error>>> for Error {
113    fn from(e: SendError<Result<VerdictResponse, Error>>) -> Self {
114        Self::ResultChannelError(e.to_string())
115    }
116}
117
118impl From<RecvError> for Error {
119    fn from(e: RecvError) -> Self {
120        Self::ResultChannelError(e.to_string())
121    }
122}
123
124impl From<Elapsed> for Error {
125    fn from(_: Elapsed) -> Self {
126        Self::Cancelled
127    }
128}