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}