Skip to main content

stoat/
error.rs

1use std::{fmt::Display, sync::Arc};
2
3use stoat_permissions::ChannelPermission;
4pub use stoat_result::{Error as StoatHttpError, ErrorType as StoatHttpErrorType};
5
6use crate::types::RatelimitFailure;
7
8pub type Result<T, E = Error> = std::result::Result<T, E>;
9
10/// All possible errors for Stoat-rs, this includes errors from dependancies like `reqwest`, `tungestenite` and `livekit`.
11///
12/// Your custom error type should implement `From<stoat::Error>` to allow errors to automatically travel up the call chain throughout your codebase.
13#[derive(Debug, Clone)]
14pub enum Error {
15    ReqwestError(Arc<reqwest::Error>),
16    HttpError(StoatHttpError),
17    RatelimitReached(RatelimitFailure),
18    WsError(Arc<tungstenite::Error>),
19    #[cfg(feature = "voice")]
20    LiveKit(Arc<livekit::RoomError>),
21    MissingParameter,
22    ConverterError(String),
23    Timeout,
24    BrokenChannel,
25    InternalError,
26    CheckFailure,
27    MissingChannelPermission {
28        permissions: ChannelPermission,
29    },
30    NotInServer,
31    NotInDM,
32    NotOwner,
33    NotNsfw,
34    InvalidTag,
35    MalformedID,
36    InvalidUrl,
37
38    NotAudioTrack,
39    NotVideoTrack,
40
41    Close,
42}
43
44impl std::error::Error for Error {}
45
46impl Display for Error {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        match self {
49            Error::ReqwestError(error) => write!(f, "Reqwest Error: {error}"),
50            Error::HttpError(error) => write!(f, "HTTP Error: {error}"),
51            Error::RatelimitReached(ratelimit_failure) => write!(f, "Ratelimit Reached: try again in {}ms", ratelimit_failure.retry_after),
52            Error::WsError(error) => write!(f, "Websocket Error: {error}"),
53            #[cfg(feature = "voice")]
54            Error::LiveKit(error) => write!(f, "Livekit Room Error: {error}"),
55            Error::MissingParameter => write!(f, "Missing Required Parameter"),
56            Error::ConverterError(error) => write!(f, "Converter Error: {error}"),
57            Error::Timeout => write!(f, "Timed out"),
58            Error::BrokenChannel => write!(f, "Broken Channel"),
59            Error::InternalError => write!(f, "Interal Error"),
60            Error::CheckFailure => write!(f, "Check Failure"),
61            Error::MissingChannelPermission { permissions } => write!(f, "Missing Required Permission {permissions}"),
62            Error::NotInServer => write!(f, "Not In Server"),
63            Error::NotInDM => write!(f, "Not In DMs"),
64            Error::NotOwner => write!(f, "Not Owner"),
65            Error::NotNsfw => write!(f, "Not In NSFW Channel"),
66            Error::InvalidTag => write!(f, "Invalid File Tag"),
67            Error::MalformedID => write!(f, "Malformed ULID ID"),
68            Error::InvalidUrl => write!(f, "Invalid URL"),
69            Error::NotAudioTrack => write!(f, "Not Audio Track"),
70            Error::NotVideoTrack => write!(f, "Not Video Track"),
71            Error::Close => write!(f, "Close"),
72        }
73    }
74}
75
76impl From<reqwest::Error> for Error {
77    fn from(value: reqwest::Error) -> Self {
78        Self::ReqwestError(Arc::new(value))
79    }
80}
81
82impl From<tungstenite::Error> for Error {
83    fn from(value: tungstenite::Error) -> Self {
84        Self::WsError(Arc::new(value))
85    }
86}
87
88#[cfg(feature = "voice")]
89impl From<livekit::RoomError> for Error {
90    fn from(value: livekit::RoomError) -> Self {
91        Self::LiveKit(Arc::new(value))
92    }
93}
94
95#[cfg(feature = "voice")]
96impl From<livekit::webrtc::RtcError> for Error {
97    fn from(value: livekit::webrtc::RtcError) -> Self {
98        Self::LiveKit(Arc::new(livekit::RoomError::Rtc(value)))
99    }
100}