eureka_mmanager/core/
error.rs

1use mangadex_api_types_rust::RelationshipType;
2use serde::Serialize;
3use std::{fmt::Display, num::TryFromIntError, ops::Deref, path::PathBuf, sync::Arc};
4
5use crate::{
6    files_dirs::messages::delete::chapter::images::DeleteChapterImagesError,
7    history::HistoryBaseError,
8};
9
10/// This is the crate Error
11#[derive(thiserror::Error, Debug)]
12pub enum Error {
13    #[error("An std::io::Error captured! \n Details : {0}")]
14    Io(#[from] std::io::Error),
15    #[error("An Error captured during sending a request \n Details : {0}")]
16    ReqwestError(#[from] reqwest::Error),
17    #[error("An Error captured from the `mangadex_api` crate \n Details : {0}")]
18    MangadexAPIError(#[from] mangadex_api_types_rust::error::Error),
19    #[error("An error occured during Joining handles \n Details : {0}")]
20    TokioJoinError(#[from] tokio::task::JoinError),
21    #[error("An error occured when parsing some string to json \n Details : {0}")]
22    SerdeJsonError(#[from] serde_json::Error),
23    #[error("An error occured when parsing an uuid \n Details : {0}")]
24    UuidError(#[from] uuid::Error),
25    #[error("An error occured when parsing bytes to UTF-8 String \n Details : {0}")]
26    StringUtf8Error(#[from] std::string::FromUtf8Error),
27    #[error("An error occured when parsing bytes to UTF-16 String \n Details : {0}")]
28    StringUTF16Error(#[from] std::string::FromUtf16Error),
29    #[error("An error occured when parsing something into a String \n Details : {0}")]
30    StringParseError(#[from] std::string::ParseError),
31    #[error("An error occured when building a mangdex_api request \n Details : {0}")]
32    MangadexBuilderError(#[from] mangadex_api_types_rust::error::BuilderError),
33    #[error("An Download Tasks limit Exceded {current}/{limit}")]
34    DownloadTaskLimitExceded { current: u16, limit: u16 },
35    #[error("An error occured when converting into a int")]
36    TryIntError(#[from] TryFromIntError),
37    #[error("An error occured when sending data between an oneshot channel \n Details: {0}")]
38    OneshotRecvError(#[from] tokio::sync::oneshot::error::RecvError),
39    #[error("An error occured when acquiring a semaphore \n Details : {0}")]
40    AcquireError(#[from] tokio::sync::AcquireError),
41    #[error("The file transaction was been roolback due to an error. Details : {0}")]
42    RollBacked(String),
43    #[error("An RwLock occured \n Details : {0}")]
44    RwLockError(#[from] std::sync::PoisonError<String>),
45    #[error("We got a {0} mailbox error")]
46    MailBox(#[from] actix::MailboxError),
47    #[error("the history file for {0} is not found")]
48    HistoryFileNotFound(RelationshipType),
49    #[error("We got an std thread join error {0}")]
50    StdThreadJoin(String),
51    #[error("We got an error when manipulation an HistoryEntry: {0}")]
52    HistoryBase(#[from] HistoryBaseError),
53    #[error("Invalid file entry {0}")]
54    InvalidFileName(PathBuf),
55    #[error(transparent)]
56    WatchRecv(#[from] tokio::sync::watch::error::RecvError),
57    #[error("The given task was been cancelled")]
58    TaskCanceled,
59    #[error("The MangaDexClient is not found")]
60    MangaDexClientNotFound,
61    #[error("The DirsOption actor is not found")]
62    DirsOptionsNotFound,
63    #[error("The HistoryService is not found")]
64    HistoryServiceNotFound,
65    #[error("The initial state can't be sent")]
66    NotInitialized,
67    #[error(transparent)]
68    ApiCore(#[from] api_core::Error),
69    #[error(transparent)]
70    DeleteChapterImages(#[from] DeleteChapterImagesError),
71}
72
73impl Error {
74    /// Transform the error into an [`OwnedError`]
75    pub fn into_owned(self) -> OwnedError {
76        self.into()
77    }
78    /// Transform the error into an [`ErrorType`]
79    pub fn into_type(&self) -> ErrorType {
80        self.into()
81    }
82}
83
84/// This is just [`Error`] wrapped into an [`Arc`],
85/// allows you to share the error "safely" between thread
86/// since [`Error`] doesn't implement [`Clone`].
87///
88/// If you don't want the value or want a light-weight alternative to this, use [`ErrorType`] instead
89#[derive(Debug, Clone)]
90pub struct OwnedError(Arc<Error>);
91
92impl Deref for OwnedError {
93    type Target = Arc<Error>;
94    fn deref(&self) -> &Self::Target {
95        &self.0
96    }
97}
98
99impl From<Arc<Error>> for OwnedError {
100    fn from(value: Arc<Error>) -> Self {
101        Self(value)
102    }
103}
104
105impl From<Error> for OwnedError {
106    fn from(value: Error) -> Self {
107        Arc::new(value).into()
108    }
109}
110
111impl Display for OwnedError {
112    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113        self.deref().as_ref().fmt(f)
114    }
115}
116
117impl std::error::Error for OwnedError {
118    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
119        self.deref().as_ref().source()
120    }
121}
122
123/// This is just [`Error`] but without the values.
124///
125/// You can get it by using [`Into::into`] on [`Error`] or use [`Error::into_type`].
126///
127/// It can be useful if you just want or share the error without using [`OwnedError`]
128#[derive(
129    serde::Serialize, Debug, serde::Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
130)]
131pub enum ErrorType {
132    Io,
133    ReqwestError,
134    MangadexAPIError,
135    TokioJoinError,
136    SerdeJsonError,
137    UuidError,
138    StringUtf8Error,
139    StringUTF16Error,
140    StringParseError,
141    MangadexBuilderError,
142    DownloadTaskLimitExceded,
143    TryIntError,
144    OneshotRecvError,
145    AcquireError,
146    RollBacked,
147    RwLockError,
148    MailBox,
149    HistoryFileNotFound,
150    StdThreadJoin,
151    HistoryBase,
152    InvalidFileName,
153    MissingRelationships,
154    DeleteChapterImages,
155    WatchRecv,
156    TaskCanceled,
157    MangaDexClientNotFound,
158    HistoryServiceNotFound,
159    NotInitialized,
160    ApiCore,
161    DirsOptionsNotFound,
162}
163
164impl From<&Error> for ErrorType {
165    fn from(value: &Error) -> Self {
166        match value {
167            Error::Io(_) => Self::Io,
168            Error::ReqwestError(_) => Self::ReqwestError,
169            Error::MangadexAPIError(_) => Self::MangadexAPIError,
170            Error::TokioJoinError(_) => Self::TokioJoinError,
171            Error::SerdeJsonError(_) => Self::SerdeJsonError,
172            Error::UuidError(_) => Self::UuidError,
173            Error::StringUtf8Error(_) => Self::StringUtf8Error,
174            Error::StringUTF16Error(_) => Self::StringUTF16Error,
175            Error::StringParseError(_) => Self::StringParseError,
176            Error::MangadexBuilderError(_) => Self::MangadexBuilderError,
177            Error::DownloadTaskLimitExceded { .. } => Self::DownloadTaskLimitExceded,
178            Error::TryIntError(_) => Self::TryIntError,
179            Error::OneshotRecvError(_) => Self::OneshotRecvError,
180            Error::AcquireError(_) => Self::AcquireError,
181            Error::RollBacked(_) => Self::RollBacked,
182            Error::RwLockError(_) => Self::RwLockError,
183            Error::MailBox(_) => Self::MailBox,
184            Error::HistoryFileNotFound(_) => Self::HistoryFileNotFound,
185            Error::StdThreadJoin(_) => Self::StdThreadJoin,
186            Error::HistoryBase(_) => Self::HistoryBase,
187            Error::InvalidFileName(_) => Self::InvalidFileName,
188            Error::WatchRecv(_) => Self::WatchRecv,
189            Error::TaskCanceled => Self::TaskCanceled,
190            Error::MangaDexClientNotFound => Self::MangaDexClientNotFound,
191            Error::DirsOptionsNotFound => Self::DirsOptionsNotFound,
192            Error::HistoryServiceNotFound => Self::HistoryServiceNotFound,
193            Error::NotInitialized => Self::NotInitialized,
194            Error::ApiCore(_) => Self::ApiCore,
195            Error::DeleteChapterImages(_) => Self::DeleteChapterImages,
196        }
197    }
198}
199
200impl From<Error> for ErrorType {
201    fn from(value: Error) -> Self {
202        (&value).into()
203    }
204}
205
206impl Serialize for Error {
207    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
208    where
209        S: serde::Serializer,
210    {
211        serializer.serialize_str(self.to_string().as_str())
212    }
213}