feat: handle error 400 for invalid ctokens
This commit is contained in:
parent
f7fbf40721
commit
cc50862408
4 changed files with 64 additions and 9 deletions
|
|
@ -29,7 +29,7 @@ use log::{debug, error, warn};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use reqwest::{header, Client, ClientBuilder, Request, RequestBuilder, Response};
|
use reqwest::{header, Client, ClientBuilder, Request, RequestBuilder, Response, StatusCode};
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
use time::{Duration, OffsetDateTime};
|
use time::{Duration, OffsetDateTime};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
@ -1087,14 +1087,25 @@ impl RustyPipeQuery {
|
||||||
|
|
||||||
if status.is_client_error() || status.is_server_error() {
|
if status.is_client_error() || status.is_server_error() {
|
||||||
let status_code = status.as_u16();
|
let status_code = status.as_u16();
|
||||||
return if status_code == 404 {
|
|
||||||
Err(Error::Extraction(ExtractionError::ContentUnavailable(
|
return match status {
|
||||||
"Not found".into(),
|
StatusCode::NOT_FOUND => Err(Error::Extraction(
|
||||||
)))
|
ExtractionError::ContentUnavailable("404 Not found".into()),
|
||||||
} else {
|
)),
|
||||||
let e = Error::HttpStatus(status_code);
|
StatusCode::BAD_REQUEST => {
|
||||||
create_report(Level::ERR, Some(e.to_string()), vec![]);
|
let error_res = serde_json::from_str::<response::ErrorResponse>(&resp_str);
|
||||||
Err(e)
|
Err(Error::Extraction(ExtractionError::BadRequest(
|
||||||
|
error_res
|
||||||
|
.map(|r| r.error.message)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.into(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let e = Error::HttpStatus(status_code);
|
||||||
|
create_report(Level::ERR, Some(e.to_string()), vec![]);
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,20 @@ pub(crate) struct MusicContinuationDataInner {
|
||||||
pub continuation: String,
|
pub continuation: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ERROR
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub(crate) struct ErrorResponse {
|
||||||
|
pub error: ErrorResponseContent,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub(crate) struct ErrorResponseContent {
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#MAPPING
|
#MAPPING
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,9 @@ pub enum ExtractionError {
|
||||||
/// Content is not available / does not exist
|
/// Content is not available / does not exist
|
||||||
#[error("Content is not available. Reason: {0}")]
|
#[error("Content is not available. Reason: {0}")]
|
||||||
ContentUnavailable(Cow<'static, str>),
|
ContentUnavailable(Cow<'static, str>),
|
||||||
|
/// Bad request (Error 400 from YouTube), probably invalid input parameters
|
||||||
|
#[error("Bad request. Reason: {0}")]
|
||||||
|
BadRequest(Cow<'static, str>),
|
||||||
/// Error deserializing YouTube's response JSON
|
/// Error deserializing YouTube's response JSON
|
||||||
#[error("deserialization error: {0}")]
|
#[error("deserialization error: {0}")]
|
||||||
Deserialization(#[from] serde_json::Error),
|
Deserialization(#[from] serde_json::Error),
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use std::collections::HashSet;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use rstest::rstest;
|
use rstest::rstest;
|
||||||
|
use rustypipe::model::paginator::ContinuationEndpoint;
|
||||||
use rustypipe::validate;
|
use rustypipe::validate;
|
||||||
use time::macros::date;
|
use time::macros::date;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
|
|
@ -2219,6 +2220,32 @@ async fn ab3_search_channel_handles() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#MISCELLANEOUS
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case::desktop(ContinuationEndpoint::Browse)]
|
||||||
|
#[case::music(ContinuationEndpoint::MusicBrowse)]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn invalid_ctoken(#[case] ep: ContinuationEndpoint) {
|
||||||
|
let rp = RustyPipe::builder().strict().build();
|
||||||
|
|
||||||
|
let e = rp
|
||||||
|
.query()
|
||||||
|
.continuation::<YouTubeItem, _>("Abcd", ep, None)
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
|
match e {
|
||||||
|
Error::Extraction(e) => match e {
|
||||||
|
ExtractionError::BadRequest(msg) => {
|
||||||
|
assert_eq!(msg, "Request contains an invalid argument.")
|
||||||
|
}
|
||||||
|
_ => panic!("invalid error: {}", e),
|
||||||
|
},
|
||||||
|
_ => panic!("invalid error: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//#TESTUTIL
|
//#TESTUTIL
|
||||||
|
|
||||||
/// Assert equality within 10% margin
|
/// Assert equality within 10% margin
|
||||||
|
|
|
||||||
Reference in a new issue