forked from mirror/Riven
Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
Mingwei Samuel | 58d693e5ee | |
Mingwei Samuel | 43d7f607a1 | |
Michal Baumgartner | 60317be114 | |
Michal Baumgartner | 169fa50f63 | |
Michal Baumgartner | d5494ba442 |
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "riven"
|
name = "riven"
|
||||||
version = "1.1.0"
|
version = "2.0.0-alpha.0"
|
||||||
authors = ["Mingwei Samuel <mingwei.samuel@gmail.com>"]
|
authors = ["Mingwei Samuel <mingwei.samuel@gmail.com>"]
|
||||||
repository = "https://github.com/MingweiSamuel/Riven"
|
repository = "https://github.com/MingweiSamuel/Riven"
|
||||||
description = "Riot Games API Library"
|
description = "Riot Games API Library"
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
||||||
// Version 71bb788ab92c0b03d5dd284402d9514b625fe2a4
|
// Version 64f3c82d132f12808d8eb8f483d1d2182386c432
|
||||||
|
|
||||||
//! Automatically generated endpoint handles.
|
//! Automatically generated endpoint handles.
|
||||||
|
|
||||||
|
@ -261,6 +261,8 @@ pub struct ClashV1<'a> {
|
||||||
}
|
}
|
||||||
impl<'a> ClashV1<'a> {
|
impl<'a> ClashV1<'a> {
|
||||||
/// Get players by summoner ID.
|
/// Get players by summoner ID.
|
||||||
|
/// ## Implementation Notes
|
||||||
|
/// This endpoint returns a list of active Clash players for a given summoner ID. If a summoner registers for multiple tournaments at the same time (e.g., Saturday and Sunday) then both registrations would appear in this list.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
/// * `summonerId`
|
/// * `summonerId`
|
||||||
|
|
34
src/error.rs
34
src/error.rs
|
@ -4,7 +4,7 @@ use std::fmt;
|
||||||
/// Re-exported `reqwest` types.
|
/// Re-exported `reqwest` types.
|
||||||
pub mod reqwest {
|
pub mod reqwest {
|
||||||
pub use reqwest::{
|
pub use reqwest::{
|
||||||
Error, Response, StatusCode, Url
|
Error, Response, StatusCode, Url, header::HeaderMap
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
use ::reqwest::*;
|
use ::reqwest::*;
|
||||||
|
@ -20,16 +20,24 @@ pub type Result<T> = std::result::Result<T, RiotApiError>;
|
||||||
pub struct RiotApiError {
|
pub struct RiotApiError {
|
||||||
reqwest_error: Error,
|
reqwest_error: Error,
|
||||||
retries: u8,
|
retries: u8,
|
||||||
response: Option<Response>,
|
headers: Option<header::HeaderMap>,
|
||||||
status_code: Option<StatusCode>,
|
status_code: Option<StatusCode>,
|
||||||
|
response_body: Option<String>,
|
||||||
}
|
}
|
||||||
impl RiotApiError {
|
impl RiotApiError {
|
||||||
pub(crate) fn new(reqwest_error: Error, retries: u8, response: Option<Response>, status_code: Option<StatusCode>) -> Self {
|
pub(crate) fn new(
|
||||||
|
reqwest_error: Error,
|
||||||
|
retries: u8,
|
||||||
|
headers: Option<header::HeaderMap>,
|
||||||
|
status_code: Option<StatusCode>,
|
||||||
|
response_body: Option<String>
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
reqwest_error: reqwest_error,
|
reqwest_error: reqwest_error,
|
||||||
retries: retries,
|
retries: retries,
|
||||||
response: response,
|
headers: headers,
|
||||||
status_code: status_code,
|
status_code: status_code,
|
||||||
|
response_body: response_body,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// The reqwest::Error for the final failed request.
|
/// The reqwest::Error for the final failed request.
|
||||||
|
@ -40,18 +48,24 @@ impl RiotApiError {
|
||||||
pub fn retries(&self) -> u8 {
|
pub fn retries(&self) -> u8 {
|
||||||
self.retries
|
self.retries
|
||||||
}
|
}
|
||||||
/// The failed response.
|
|
||||||
/// `Some(reqwest::Response)` if the request was sent and failed.
|
|
||||||
/// `None` if the request was not sent, OR if parsing the response JSON failed.
|
|
||||||
pub fn response(&self) -> Option<&Response> {
|
|
||||||
self.response.as_ref()
|
|
||||||
}
|
|
||||||
/// The failed response's HTTP status code.
|
/// The failed response's HTTP status code.
|
||||||
/// `Some(reqwest::StatusCode)` if the request was sent and failed, OR if parsing the response JSON failed.
|
/// `Some(reqwest::StatusCode)` if the request was sent and failed, OR if parsing the response JSON failed.
|
||||||
/// `None` if the request was not sent.
|
/// `None` if the request was not sent.
|
||||||
pub fn status_code(&self) -> Option<StatusCode> {
|
pub fn status_code(&self) -> Option<StatusCode> {
|
||||||
self.status_code
|
self.status_code
|
||||||
}
|
}
|
||||||
|
/// The failed response's headers.
|
||||||
|
/// `Some(reqwest::header::HeaderMap)` if the request was sent and failed.
|
||||||
|
/// `None` if the request was not sent.
|
||||||
|
pub fn headers(&self) -> Option<header::HeaderMap> {
|
||||||
|
self.headers.clone()
|
||||||
|
}
|
||||||
|
/// The failed response's body (as a copy).
|
||||||
|
/// `Some(String)` if the request was sent and failed.
|
||||||
|
/// `None` if the request was not sent.
|
||||||
|
pub fn response_body(&self) -> Option<String> {
|
||||||
|
self.response_body.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl fmt::Display for RiotApiError {
|
impl fmt::Display for RiotApiError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
||||||
// Version 71bb788ab92c0b03d5dd284402d9514b625fe2a4
|
// Version 64f3c82d132f12808d8eb8f483d1d2182386c432
|
||||||
|
|
||||||
//! Data transfer structs.
|
//! Data transfer structs.
|
||||||
//!
|
//!
|
||||||
|
@ -466,7 +466,7 @@ pub mod match_v4 {
|
||||||
pub struct ParticipantIdentity {
|
pub struct ParticipantIdentity {
|
||||||
#[serde(rename = "participantId")]
|
#[serde(rename = "participantId")]
|
||||||
pub participant_id: i32,
|
pub participant_id: i32,
|
||||||
/// Player information.
|
/// Player information not included in the response for custom matches. Custom matches are considered private unless a tournament code was used to create the match.
|
||||||
#[serde(rename = "player")]
|
#[serde(rename = "player")]
|
||||||
pub player: Player,
|
pub player: Player,
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,20 +86,22 @@ impl RegionalRequester {
|
||||||
.header(Self::RIOT_KEY_HEADER, &*config.api_key)
|
.header(Self::RIOT_KEY_HEADER, &*config.api_key)
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| RiotApiError::new(e, retries, None, None))?;
|
.map_err(|e| RiotApiError::new(e, retries, None, None, None))?;
|
||||||
|
|
||||||
// Maybe update rate limits (based on response headers).
|
// Maybe update rate limits (based on response headers).
|
||||||
self.app_rate_limit.on_response(&config, &response);
|
self.app_rate_limit.on_response(&config, &response);
|
||||||
method_rate_limit.on_response(&config, &response);
|
method_rate_limit.on_response(&config, &response);
|
||||||
|
|
||||||
let status = response.status();
|
let status = response.status();
|
||||||
|
let headers = response.headers().clone();
|
||||||
|
|
||||||
// Handle normal success / failure cases.
|
// Handle normal success / failure cases.
|
||||||
match response.error_for_status_ref() {
|
match response.error_for_status_ref() {
|
||||||
// Success.
|
// Success.
|
||||||
Ok(_response) => {
|
Ok(_response) => {
|
||||||
log::trace!("Response {} (retried {} times), parsed result.", status, retries);
|
log::trace!("Response {} (retried {} times), parsed result.", status, retries);
|
||||||
let value = response.json::<T>().await;
|
let value = response.json::<T>().await;
|
||||||
break value.map_err(|e| RiotApiError::new(e, retries, None, Some(status)));
|
break value.map_err(|e| RiotApiError::new(e, retries, Some(headers), Some(status), None));
|
||||||
},
|
},
|
||||||
// Failure, may or may not be retryable.
|
// Failure, may or may not be retryable.
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -110,7 +112,20 @@ impl RegionalRequester {
|
||||||
&& !status.is_server_error())
|
&& !status.is_server_error())
|
||||||
{
|
{
|
||||||
log::debug!("Response {} (retried {} times), returning.", status, retries);
|
log::debug!("Response {} (retried {} times), returning.", status, retries);
|
||||||
break Err(RiotApiError::new(err, retries, Some(response), Some(status)));
|
|
||||||
|
// Extract the response body as a String
|
||||||
|
let content = response.text().await;
|
||||||
|
|
||||||
|
break match content {
|
||||||
|
Ok(str) => {
|
||||||
|
Err(RiotApiError::new(err, retries, Some(headers), Some(status), Some(str)))
|
||||||
|
}
|
||||||
|
Err(_inner_err) => {
|
||||||
|
// Throw the inner error away and ignore response body parsing
|
||||||
|
|
||||||
|
Err(RiotApiError::new(err, retries, Some(headers), Some(status), None))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
log::debug!("Response {} (retried {} times), retrying.", status, retries);
|
log::debug!("Response {} (retried {} times), retrying.", status, retries);
|
||||||
},
|
},
|
||||||
|
|
|
@ -49,6 +49,31 @@ async_tests!{
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
|
inspecting_response_and_headers_on_error: async {
|
||||||
|
let sum = RIOT_API.summoner_v4().get_by_puuid(Region::EUW, "clearly not a puuid").await;
|
||||||
|
|
||||||
|
match sum {
|
||||||
|
Ok(_summoner) => rassert!(false, "Should not have succeeded"),
|
||||||
|
Err(error) => {
|
||||||
|
match error.headers() {
|
||||||
|
Some(headers) => {
|
||||||
|
rassert!(headers.len() > 0, "Invalid headers received: {:?}", error);
|
||||||
|
rassert!(headers.contains_key("x-app-rate-limit"), "Invalid headers received: {:?}", error);
|
||||||
|
rassert!(headers.contains_key("x-method-rate-limit"), "Invalid headers received: {:?}", error);
|
||||||
|
},
|
||||||
|
None => rassert!(false, "Headers shouldn't be empty"),
|
||||||
|
}
|
||||||
|
match error.response_body() {
|
||||||
|
Some(body) => {
|
||||||
|
rassert!(body.len() > 0, "Invalid body received: {:?}", error);
|
||||||
|
},
|
||||||
|
None => rassert!(false, "The response body shouldn't be empty"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
// // TFT tests.
|
// // TFT tests.
|
||||||
// tftleaguev1_getchallengerleague: async {
|
// tftleaguev1_getchallengerleague: async {
|
||||||
// let p = RIOT_API.tft_league_v1().get_challenger_league(Region::EUW);
|
// let p = RIOT_API.tft_league_v1().get_challenger_league(Region::EUW);
|
||||||
|
|
Loading…
Reference in New Issue