Skip to main content

steamkit/util/
steam_kit_web_request_exception.rs

1//! The error of a failed HTTP request.
2
3use std::fmt;
4
5use reqwest::header::HeaderMap;
6use reqwest::{Response, StatusCode};
7
8use crate::error::SteamError;
9
10/// A failed HTTP request.
11pub struct SteamKitWebRequestException {
12    /// What went wrong.
13    message: String,
14    /// The status code of the response.
15    status_code: StatusCode,
16    /// The headers of the response.
17    headers: HeaderMap,
18    /// The underlying error, if any.
19    source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
20}
21
22impl SteamKitWebRequestException {
23    /// Creates the error for a response, keeping its status code and headers.
24    pub fn new(message: impl Into<String>, response: &Response) -> SteamKitWebRequestException {
25        SteamKitWebRequestException {
26            message: message.into(),
27            status_code: response.status(),
28            headers: response.headers().clone(),
29            source: None,
30        }
31    }
32
33    /// Creates the error from just a message. The status code is `200 OK` and
34    /// there are no headers.
35    pub fn from_message(message: impl Into<String>) -> SteamKitWebRequestException {
36        SteamKitWebRequestException {
37            message: message.into(),
38            status_code: StatusCode::OK,
39            headers: HeaderMap::new(),
40            source: None,
41        }
42    }
43
44    /// Creates the error from a message and an underlying error.
45    pub fn with_source(
46        message: impl Into<String>,
47        source: impl std::error::Error + Send + Sync + 'static,
48    ) -> SteamKitWebRequestException {
49        SteamKitWebRequestException {
50            message: message.into(),
51            status_code: StatusCode::OK,
52            headers: HeaderMap::new(),
53            source: Some(Box::new(source)),
54        }
55    }
56
57    /// The status code of the response.
58    pub fn status_code(&self) -> StatusCode {
59        self.status_code
60    }
61
62    /// The headers of the response.
63    pub fn headers(&self) -> &HeaderMap {
64        &self.headers
65    }
66
67    /// What went wrong.
68    pub fn message(&self) -> &str {
69        &self.message
70    }
71}
72
73impl Default for SteamKitWebRequestException {
74    fn default() -> SteamKitWebRequestException {
75        SteamKitWebRequestException {
76            message: String::new(),
77            status_code: StatusCode::OK,
78            headers: HeaderMap::new(),
79            source: None,
80        }
81    }
82}
83
84impl fmt::Display for SteamKitWebRequestException {
85    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
86        write!(
87            formatter,
88            "{} (HTTP {})",
89            self.message,
90            self.status_code.as_u16()
91        )
92    }
93}
94
95impl fmt::Debug for SteamKitWebRequestException {
96    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
97        formatter
98            .debug_struct("SteamKitWebRequestException")
99            .field("message", &self.message)
100            .field("status_code", &self.status_code)
101            .field("headers", &self.headers)
102            .field("source", &self.source.as_ref().map(|error| error.to_string()))
103            .finish()
104    }
105}
106
107impl std::error::Error for SteamKitWebRequestException {
108    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
109        self.source
110            .as_ref()
111            .map(|error| error.as_ref() as &(dyn std::error::Error + 'static))
112    }
113}
114
115impl From<SteamKitWebRequestException> for SteamError {
116    fn from(value: SteamKitWebRequestException) -> Self {
117        SteamError::Other(value.to_string())
118    }
119}