1use steam_enums::EResult;
4use thiserror::Error;
5
6#[derive(Error, Debug)]
8pub enum SessionError {
9 #[error("Invalid credentials")]
10 InvalidCredentials,
11
12 #[error("Steam Guard code required")]
13 SteamGuardRequired,
14
15 #[error("Two-factor code required")]
16 TwoFactorRequired,
17
18 #[error("Invalid Steam Guard code")]
19 InvalidSteamGuardCode,
20
21 #[error("Invalid two-factor code")]
22 InvalidTwoFactorCode,
23
24 #[error("Rate limited")]
25 RateLimited,
26
27 #[error("Session expired")]
28 SessionExpired,
29
30 #[error("Network error: {0}")]
31 NetworkError(String),
32
33 #[error("Token error: {0}")]
34 TokenError(String),
35
36 #[error("Steam error: {0} (EResult: {1:?})")]
37 SteamError(String, EResult),
38
39 #[error("Invalid JWT format")]
40 InvalidJwt,
41
42 #[error("Invalid QR code URL: {0}")]
43 InvalidQrUrl(String),
44
45 #[error("Login session not started")]
46 NotStarted,
47
48 #[error("Login attempt canceled")]
49 Canceled,
50
51 #[error("Login timeout")]
52 Timeout,
53
54 #[error("Cannot use this method with current login state")]
55 InvalidState,
56
57 #[error("Protobuf encode error: {0}")]
58 ProtobufEncode(#[from] prost::EncodeError),
59
60 #[error("Protobuf decode error: {0}")]
61 ProtobufDecode(#[from] prost::DecodeError),
62
63 #[error("RSA encryption error: {0}")]
64 RsaError(#[from] rsa::errors::Error),
65
66 #[error("Crypto error: {0}")]
67 CryptoError(String),
68
69 #[error("HTTP error: {0}")]
70 HttpError(#[from] reqwest::Error),
71
72 #[error("WebSocket error: {0}")]
73 WebSocketError(Box<tokio_tungstenite::tungstenite::Error>),
74
75 #[error("Protocol error: {0}")]
76 ProtocolError(String),
77
78 #[error("JSON error: {0}")]
79 Json(#[from] serde_json::Error),
80
81 #[error("Base64 error: {0}")]
82 Base64(#[from] base64::DecodeError),
83
84 #[error("I/O error: {0}")]
85 Io(#[from] std::io::Error),
86}
87
88impl From<tokio_tungstenite::tungstenite::Error> for SessionError {
89 fn from(err: tokio_tungstenite::tungstenite::Error) -> Self {
90 SessionError::WebSocketError(Box::new(err))
91 }
92}
93
94impl SessionError {
95 pub fn from_eresult(result: i32, message: Option<String>) -> Self {
97 let eresult = match EResult::from_i32(result) {
98 Some(e) => e,
99 None => {
100 tracing::warn!("Unknown EResult code: {}", result);
101 EResult::Invalid
102 }
103 };
104 let msg = message.unwrap_or_else(|| format!("{:?}", eresult));
105 SessionError::SteamError(msg, eresult)
106 }
107}