steam_trading/
errors.rs

1use steam_language_gen::generated::enums::EResult;
2use steam_mobile::errors::AuthError;
3use steam_mobile::HttpError;
4use tappet::errors::SteamAPIError;
5use thiserror::Error;
6
7#[derive(Error, Debug)]
8#[non_exhaustive]
9pub enum TradeError {
10    #[error("`{0}`")]
11    GeneralError(String),
12
13    #[error(transparent)]
14    TradeOfferError(#[from] OfferError),
15
16    #[error(transparent)]
17    TradeValidationError(#[from] OfferValidationError),
18
19    #[error(transparent)]
20    SteamAPIError(#[from] SteamAPIError),
21
22    #[error(transparent)]
23    ConfirmationError(#[from] ConfirmationError),
24
25    #[error(transparent)]
26    AuthError(#[from] AuthError),
27
28    #[error(transparent)]
29    InternalError(#[from] InternalError),
30}
31
32#[derive(Error, Debug)]
33pub enum InternalError {
34    #[error(transparent)]
35    NetworkError(#[from] HttpError),
36
37    #[error(transparent)]
38    MobileInternalError(#[from] steam_mobile::errors::InternalError),
39}
40
41#[derive(Error, Debug, PartialEq, Copy, Clone)]
42pub enum TradelinkError {
43    #[error("The Tradeoffer URL was not valid.")]
44    Invalid,
45}
46
47#[derive(Error, Debug, PartialEq)]
48#[non_exhaustive]
49pub enum OfferValidationError {
50    #[error(transparent)]
51    TradelinkError(#[from] TradelinkError),
52
53    #[error("`{0}`")]
54    InvalidTrade(String),
55}
56
57#[derive(Error, Debug, PartialEq)]
58#[non_exhaustive]
59pub enum OfferError {
60    #[error(
61        "This trade offer is in an invalid state, and cannot be acted upon. Perhaps you are trying to cancel a trade \
62         offer that was already canceled, or something similar."
63    )]
64    InvalidState,
65
66    #[error(
67        "This trade offer id could not be found. It may be already canceled or even accepted.Are you sure this is the \
68         correct id?"
69    )]
70    NoMatch,
71
72    #[error(
73        "This response code suggests that one or more of the items in this trade offer does not exist in the \
74         inventory from which it was requested."
75    )]
76    Revoked,
77
78    #[error(
79        "This suggests that the user receiving the trade offer recently activated his mobile SteamGuard and is under \
80         the 7 day restriction period."
81    )]
82    SteamGuardRecentlyEnabled,
83
84    #[error("General Failure: `{0}`")]
85    GeneralFailure(String),
86}
87
88#[derive(Error, Debug, Copy, Clone)]
89pub enum ConfirmationError {
90    #[error("Could not find the requested confirmation.")]
91    NotFound,
92    #[error("Could not find the requested confirmation, but offer was created. Trade offer id: `{0}`")]
93    NotFoundButTradeCreated(u64),
94}
95
96pub fn tradeoffer_error_from_eresult(eresult: EResult) -> OfferError {
97    match eresult {
98        EResult::Revoked => OfferError::Revoked,
99        EResult::InvalidState => OfferError::InvalidState,
100        EResult::NoMatch => OfferError::NoMatch,
101        e => OfferError::GeneralFailure(format!(
102            "{}{}",
103            "Please check: https://steamerrors.com/",
104            &*serde_json::to_string(&e).unwrap()
105        )),
106    }
107}
108
109pub fn error_from_strmessage(message: &str) -> Option<OfferError> {
110    let index_start = message.find(|c: char| c == '(')?;
111    let index_end = message.find(|c: char| c == ')')?;
112
113    let number = message
114        .chars()
115        .skip(index_start + 1)
116        .take(index_end - index_start - 1)
117        .collect::<String>();
118
119    serde_json::from_str::<EResult>(&*number)
120        .map(tradeoffer_error_from_eresult)
121        .ok()
122}
123
124#[cfg(test)]
125mod tests {
126    use super::*;
127
128    #[test]
129    fn error_strmessage() {
130        let error_message = "Something went wrong (26)";
131        assert_eq!(error_from_strmessage(error_message).unwrap(), OfferError::Revoked)
132    }
133}