From 79ad933e91adc2ea2f4101fc26c8ad4e3183dca3 Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Wed, 23 Oct 2019 00:39:40 -0700 Subject: [PATCH] Updating to use custom error struct, adding docs --- src/consts/champion.rs | 2 +- src/consts/mod.rs | 2 ++ src/consts/region.rs | 4 +++ src/endpoints.rs | 4 ++- src/endpoints/dto.rs | 2 +- src/lib.rs | 6 +++-- src/req/regional_requester.rs | 9 ++++--- src/riot_api.rs | 4 ++- src/riot_api_config.rs | 1 + src/riot_api_error.rs | 50 +++++++++++++++++++++++++++++++++++ srcgen/dotUtils.js | 7 +++++ srcgen/endpoints.rs.dt | 2 ++ srcgen/index.js | 4 +++ 13 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 src/riot_api_error.rs diff --git a/src/consts/champion.rs b/src/consts/champion.rs index 7bdc770..8091da2 100644 --- a/src/consts/champion.rs +++ b/src/consts/champion.rs @@ -1,7 +1,7 @@  // This file is automatically generated. // Do not directly edit. -// Generated on 2019-10-23T01:41:03.103Z +// Generated on 2019-10-23T07:19:13.049Z use std::fmt; use num_derive; diff --git a/src/consts/mod.rs b/src/consts/mod.rs index 013291a..aeb57eb 100644 --- a/src/consts/mod.rs +++ b/src/consts/mod.rs @@ -1,3 +1,5 @@ +//! Constant data and Enums relevant to the Riot Games API. + mod region; mod champion; diff --git a/src/consts/region.rs b/src/consts/region.rs index 69add5f..25165ca 100644 --- a/src/consts/region.rs +++ b/src/consts/region.rs @@ -1,3 +1,6 @@ +//! A region served by a single game server. +//! Each Riot Games API request is directed at a particular region, +//! with tournament API requests directed at the AMERICAS "global" region. #[derive(Debug)] #[derive(PartialEq, Eq, Hash, PartialOrd, Ord)] #[derive(Clone, Copy)] @@ -54,6 +57,7 @@ impl Region { AMERICAS => "AMERICAS"; EUROPE => "EUROPE"; ASIA => "ASIA"; + } } diff --git a/src/endpoints.rs b/src/endpoints.rs index 28da537..840cd80 100644 --- a/src/endpoints.rs +++ b/src/endpoints.rs @@ -1,11 +1,13 @@ // This file is automatically generated. // Do not directly edit. -// Generated on 2019-10-23T01:41:03.165Z +// Generated on 2019-10-23T07:19:13.042Z // http://www.mingweisamuel.com/riotapi-schema/tool/ // Version 0c74167e0eaaeb6de1c7e8219fecaabcf8386d1f +//! Automatically generated endpoint handles and data transfer structs. + mod dto; pub use dto::*; diff --git a/src/endpoints/dto.rs b/src/endpoints/dto.rs index 0242bef..6d7ec33 100644 --- a/src/endpoints/dto.rs +++ b/src/endpoints/dto.rs @@ -1,7 +1,7 @@ // This file is automatically generated. // Do not directly edit. -// Generated on 2019-10-23T01:41:03.173Z +// Generated on 2019-10-23T07:19:13.050Z // http://www.mingweisamuel.com/riotapi-schema/tool/ // Version 0c74167e0eaaeb6de1c7e8219fecaabcf8386d1f diff --git a/src/lib.rs b/src/lib.rs index 551d54b..9837e36 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,7 @@ -pub use reqwest::Error as Error; -pub use reqwest::Result as Result; +//! Module docs TODO. + +mod riot_api_error; +pub use riot_api_error::*; pub mod consts; diff --git a/src/req/regional_requester.rs b/src/req/regional_requester.rs index 8a3c6d2..1d4c5e3 100644 --- a/src/req/regional_requester.rs +++ b/src/req/regional_requester.rs @@ -6,6 +6,7 @@ use reqwest::{ Client, StatusCode, Url }; use tokio_timer::delay_for; use crate::Result; +use crate::RiotApiError; use crate::riot_api_config::RiotApiConfig; use crate::consts::Region; use crate::util::InsertOnlyCHashMap; @@ -63,7 +64,8 @@ impl RegionalRequester { let response = client.get(url) .header(Self::RIOT_KEY_HEADER, &*config.api_key) .send() - .await?; + .await + .map_err(|e| RiotApiError::new(e, retries, None))?; // Maybe update rate limits (based on response headers). self.app_rate_limit.on_response(&response); @@ -81,7 +83,8 @@ impl RegionalRequester { // Success. Ok(_) => { let value = response.json::().await; - break value.map(|v| Some(v)); + break value.map(|v| Some(v)) + .map_err(|e| RiotApiError::new(e, retries, None)); }, // Failure, may or may not be retryable. Err(err) => { @@ -91,7 +94,7 @@ impl RegionalRequester { (StatusCode::TOO_MANY_REQUESTS != status && !status.is_server_error()) { - break Err(err); + break Err(RiotApiError::new(err, retries, Some(response))); } }, }; diff --git a/src/riot_api.rs b/src/riot_api.rs index c7ba653..8051ea7 100644 --- a/src/riot_api.rs +++ b/src/riot_api.rs @@ -3,11 +3,13 @@ use std::future::Future; use log; use reqwest::Client; +use crate::Result; use crate::RiotApiConfig; use crate::consts::Region; use crate::req::RegionalRequester; use crate::util::InsertOnlyCHashMap; +/// For retrieving data from the Riot Games API. pub struct RiotApi { /// Configuration settings. config: RiotApiConfig, @@ -34,7 +36,7 @@ impl RiotApi { pub fn get<'a, T: serde::de::DeserializeOwned + 'a>(&'a self, method_id: &'static str, region: Region, path: String, query: Option) - -> impl Future, reqwest::Error>> + 'a + -> impl Future>> + 'a { // TODO: max concurrent requests? Or can configure client? self.regional_requesters diff --git a/src/riot_api_config.rs b/src/riot_api_config.rs index f1e7a50..7d41afb 100644 --- a/src/riot_api_config.rs +++ b/src/riot_api_config.rs @@ -1,3 +1,4 @@ +/// Configuration for instantiating RiotApi. #[derive(Debug)] pub struct RiotApiConfig { pub api_key: String, diff --git a/src/riot_api_error.rs b/src/riot_api_error.rs new file mode 100644 index 0000000..aaa886b --- /dev/null +++ b/src/riot_api_error.rs @@ -0,0 +1,50 @@ +use std::error::Error; +use std::fmt; + +pub use reqwest::Error as ReqwestError; +pub use reqwest::Response; + +/// Result containing RiotApiError on failure. +pub type Result = std::result::Result; + +/// An error that occurred while processing a Riot API request. +/// +/// Although Riven may make multiple requests due to retries, this will always +/// contain exactly one ReqwestError for the final request which failed. +#[derive(Debug)] +pub struct RiotApiError { + reqwest_error: ReqwestError, + retries: u8, + response: Option, +} +impl RiotApiError { + pub fn new(reqwest_error: ReqwestError, retries: u8, response: Option) -> Self { + Self { + reqwest_error: reqwest_error, + retries: retries, + response: response, + } + } + /// The ReqwestError for the final failed request. + pub fn source_reqwest_error(&self) -> &ReqwestError { + &self.reqwest_error + } + /// The number of retires attempted. Zero means exactly one request, zero retries. + pub fn retries(&self) -> u8 { + self.retries + } + /// The failed response, if the request sent. + pub fn response<'a>(&self) -> Option<&Response> { + self.response.as_ref() + } +} +impl fmt::Display for RiotApiError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:#?}", self) + } +} +impl Error for RiotApiError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + Some(&self.reqwest_error) + } +} diff --git a/srcgen/dotUtils.js b/srcgen/dotUtils.js index 264bba9..7bc2f62 100644 --- a/srcgen/dotUtils.js +++ b/srcgen/dotUtils.js @@ -13,6 +13,12 @@ Array.prototype.groupBy = function(lambda) { }, {})); } +function preamble() { + return `// This file is automatically generated. +// Do not directly edit. +// Generated on ${(new Date).toISOString()}.`; +} + function capitalize(input) { return input[0].toUpperCase() + input.slice(1); } @@ -112,6 +118,7 @@ function formatRouteArgument(route, pathParams = []) { module.exports = { changeCase, + preamble, capitalize, decapitalize, normalizeSchemaName, diff --git a/srcgen/endpoints.rs.dt b/srcgen/endpoints.rs.dt index f6287e6..e075daa 100644 --- a/srcgen/endpoints.rs.dt +++ b/srcgen/endpoints.rs.dt @@ -9,6 +9,8 @@ // http://www.mingweisamuel.com/riotapi-schema/tool/ // Version {{= spec.info.version }} +//! Automatically generated endpoint handles and data transfer structs. + mod dto; pub use dto::*; diff --git a/srcgen/index.js b/srcgen/index.js index cccbcd5..535f0ef 100644 --- a/srcgen/index.js +++ b/srcgen/index.js @@ -14,6 +14,10 @@ const files = [ [ 'http://www.mingweisamuel.com/riotapi-schema/openapi-3.0.0.json', '.spec.json' + ], + [ + 'http://static.developer.riotgames.com/docs/lol/seasons.json', + '.seasons.json' ] ]