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 rand::Rng;
|
||||
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 time::{Duration, OffsetDateTime};
|
||||
use tokio::sync::RwLock;
|
||||
|
|
@ -1087,14 +1087,25 @@ impl RustyPipeQuery {
|
|||
|
||||
if status.is_client_error() || status.is_server_error() {
|
||||
let status_code = status.as_u16();
|
||||
return if status_code == 404 {
|
||||
Err(Error::Extraction(ExtractionError::ContentUnavailable(
|
||||
"Not found".into(),
|
||||
)))
|
||||
} else {
|
||||
let e = Error::HttpStatus(status_code);
|
||||
create_report(Level::ERR, Some(e.to_string()), vec![]);
|
||||
Err(e)
|
||||
|
||||
return match status {
|
||||
StatusCode::NOT_FOUND => Err(Error::Extraction(
|
||||
ExtractionError::ContentUnavailable("404 Not found".into()),
|
||||
)),
|
||||
StatusCode::BAD_REQUEST => {
|
||||
let error_res = serde_json::from_str::<response::ErrorResponse>(&resp_str);
|
||||
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,
|
||||
}
|
||||
|
||||
// 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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@ pub enum ExtractionError {
|
|||
/// Content is not available / does not exist
|
||||
#[error("Content is not available. Reason: {0}")]
|
||||
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("deserialization error: {0}")]
|
||||
Deserialization(#[from] serde_json::Error),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use std::collections::HashSet;
|
|||
use std::fmt::Display;
|
||||
|
||||
use rstest::rstest;
|
||||
use rustypipe::model::paginator::ContinuationEndpoint;
|
||||
use rustypipe::validate;
|
||||
use time::macros::date;
|
||||
use time::OffsetDateTime;
|
||||
|
|
@ -2219,6 +2220,32 @@ async fn ab3_search_channel_handles() {
|
|||
.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
|
||||
|
||||
/// Assert equality within 10% margin
|
||||
|
|
|
|||
Reference in a new issue