Skip to content

Commit 06b2a72

Browse files
committed
update mihomo stuff so failed requests don't cause errors
only actual errors like parsing errors will be reported, any failed request due to rate limit or otherwise will just log a warning and return None.
1 parent 89e978b commit 06b2a72

11 files changed

Lines changed: 47 additions & 48 deletions

File tree

src/api/mihomo/uid/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ async fn get_mihomo(
3737
language_params: web::Query<LanguageParams>,
3838
pool: web::Data<PgPool>,
3939
) -> ApiResult<impl Responder> {
40-
let json = mihomo::get(*uid, language_params.lang, &pool).await?;
40+
let Some(json) = mihomo::get(*uid, language_params.lang, &pool).await? else {
41+
return Ok(HttpResponse::InternalServerError().body("mihomo data unavailable"));
42+
};
4143

4244
Ok(HttpResponse::Ok().json(json))
4345
}
@@ -59,7 +61,9 @@ async fn put_mihomo(
5961
) -> ApiResult<impl Responder> {
6062
let uid = *uid;
6163

62-
let json = mihomo::update_and_get(uid, language_params.lang, &pool).await?;
64+
let Some(json) = mihomo::update_and_get(uid, language_params.lang, &pool).await? else {
65+
return Ok(HttpResponse::InternalServerError().body("mihomo data unavailable"));
66+
};
6367

6468
Ok(HttpResponse::Ok().json(json))
6569
}

src/api/pages/leaderboard/uid/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ async fn get_leaderboard_entry(
4242

4343
// Wacky way to update the database in case the uid isn't in there
4444
if !database::mihomo::exists(uid, &pool).await?
45-
&& mihomo::get(uid, Language::En, &pool).await.is_err()
45+
&& mihomo::get(uid, Language::En, &pool).await?.is_none()
4646
{
4747
let region = match uid.to_string().chars().next() {
4848
Some('6') => "na",

src/api/pages/profiles/uid/mod.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ async fn get_profile(
134134
return Ok(HttpResponse::Forbidden().finish());
135135
}
136136

137-
let profile = get_profile_json(false, uid, language_params.lang, &pool).await?;
137+
let Some(profile) = get_profile_json(false, uid, language_params.lang, &pool).await? else {
138+
return Ok(HttpResponse::InternalServerError().body("failed fetching profile data"));
139+
};
138140

139141
Ok(HttpResponse::Ok().json(profile))
140142
}
@@ -177,7 +179,9 @@ async fn update_profile(
177179
return Ok(HttpResponse::Forbidden().finish());
178180
}
179181

180-
let profile = get_profile_json(true, uid, language_params.lang, &pool).await?;
182+
let Some(profile) = get_profile_json(true, uid, language_params.lang, &pool).await? else {
183+
return Ok(HttpResponse::InternalServerError().body("failed fetching profile data"));
184+
};
181185

182186
Ok(HttpResponse::Ok().json(profile))
183187
}
@@ -187,11 +191,14 @@ async fn get_profile_json(
187191
uid: i32,
188192
lang: Language,
189193
pool: &PgPool,
190-
) -> ApiResult<Profile> {
191-
let mihomo = if update {
194+
) -> ApiResult<Option<Profile>> {
195+
let Some(mihomo) = (if update {
192196
mihomo::update_and_get(uid, lang, pool).await?
193197
} else {
194198
mihomo::get(uid, lang, pool).await?
199+
})
200+
else {
201+
return Ok(None);
195202
};
196203

197204
let score_achievement = database::achievement_scores::get_by_uid(uid, pool).await?;
@@ -243,5 +250,5 @@ async fn get_profile_json(
243250
collection,
244251
};
245252

246-
Ok(profile)
253+
Ok(Some(profile))
247254
}

src/api/pom_warps_import/uid/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ async fn post_pom_warps_import(
9292

9393
// Wacky way to update the database in case the uid isn't in there
9494
if !database::mihomo::exists(uid, &pool).await?
95-
&& mihomo::get(uid, Language::En, &pool).await.is_err()
95+
&& mihomo::get(uid, Language::En, &pool).await?.is_none()
9696
{
9797
let region = match uid.to_string().chars().next() {
9898
Some('6') => "na",

src/api/scores/achievements/uid/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ async fn put_score_achievement(
5858
language_param: web::Query<LanguageParams>,
5959
pool: web::Data<PgPool>,
6060
) -> ApiResult<impl Responder> {
61-
mihomo::update_and_get(*uid, language_param.lang, &pool).await?;
61+
let _ = mihomo::update_and_get(*uid, language_param.lang, &pool).await?;
6262

6363
let score: ScoreAchievement = database::achievement_scores::get_by_uid(*uid, &pool)
6464
.await?

src/api/srgf_warps_import/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ async fn post_srgf_warps_import(
9898

9999
// Wacky way to update the database in case the uid isn't in there
100100
if !database::mihomo::exists(uid, &pool).await?
101-
&& mihomo::get(uid, Language::En, &pool).await.is_err()
101+
&& mihomo::get(uid, Language::En, &pool).await?.is_none()
102102
{
103103
let region = match uid.to_string().chars().next() {
104104
Some('6') => "na",

src/api/srs_warps_import/uid/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ async fn post_srs_warps_import(
8686

8787
// Wacky way to update the database in case the uid isn't in there
8888
if !database::mihomo::exists(uid, &pool).await?
89-
&& mihomo::get(uid, Language::En, &pool).await.is_err()
89+
&& mihomo::get(uid, Language::En, &pool).await?.is_none()
9090
{
9191
let region = match uid.to_string().chars().next() {
9292
Some('6') => "na",

src/api/users/me/uids/uid/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ async fn put_user_uid(
6767

6868
// Wacky way to update the database in case the uid isn't in there
6969
if !database::mihomo::exists(uid, &pool).await?
70-
&& mihomo::get(uid, Language::En, &pool).await.is_err()
70+
&& mihomo::get(uid, Language::En, &pool).await?.is_none()
7171
{
7272
let region = match uid.to_string().chars().next() {
7373
Some('6') => "na",

src/api/warps_import/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ async fn post_warps_import(
155155

156156
// Wacky way to update the database in case the uid isn't in there
157157
if !database::mihomo::exists(uid, &pool).await?
158-
&& mihomo::get(uid, Language::En, &pool).await.is_err()
158+
&& mihomo::get(uid, Language::En, &pool).await?.is_none()
159159
{
160160
let region = match uid.to_string().chars().next() {
161161
Some('6') => "na",

src/mihomo.rs

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use serde_json::Value;
77
use sqlx::PgPool;
88
use utoipa::ToSchema;
99

10-
use anyhow::{bail, Context, Result};
10+
use anyhow::{anyhow, Context, Result};
1111

1212
use crate::{database, Language};
1313

@@ -50,7 +50,7 @@ fn load_cached(language: &Language, uid: i32) -> Result<Option<Mihomo>> {
5050
}
5151
}
5252

53-
async fn fetch_json(url: &str, uid: i32, language: Language, label: &str) -> Result<Value> {
53+
async fn fetch_json(url: &str, uid: i32, language: Language, label: &str) -> Result<Option<Value>> {
5454
let response = reqwest::get(url)
5555
.await
5656
.with_context(|| format!("{label} request failed for uid {uid} language {language}"))?;
@@ -67,18 +67,16 @@ async fn fetch_json(url: &str, uid: i32, language: Language, label: &str) -> Res
6767
label,
6868
"response was not successful"
6969
);
70-
bail!(
71-
"{label} request returned non-success status {status} for uid {uid} language {language}"
72-
);
70+
return Ok(None);
7371
}
7472

7573
let text = response
7674
.text()
7775
.await
78-
.with_context(|| format!("mihomo {label} body read failed for uid {uid} language {language}"))?;
76+
.with_context(|| format!("{label} response text retrieval failed for uid {uid} language {language}"))?;
7977

8078
match serde_json::from_str(&text) {
81-
Ok(json) => Ok(json),
79+
Ok(json) => Ok(Some(json)),
8280
Err(err) => {
8381
warn!(
8482
uid,
@@ -90,16 +88,14 @@ async fn fetch_json(url: &str, uid: i32, language: Language, label: &str) -> Res
9088
error = %err,
9189
"response decode failed"
9290
);
93-
Err(err).with_context(|| {
94-
format!(
95-
"{label} json decode failed for uid {uid} language {language} status {status}"
96-
)
91+
Err(anyhow!("mihomo response body parsing failed")).with_context(|| {
92+
format!("{label} json decode failed for uid {uid} language {language}")
9793
})
9894
}
9995
}
10096
}
10197

102-
pub async fn get(uid: i32, language: Language, pool: &PgPool) -> Result<Value> {
98+
pub async fn get(uid: i32, language: Language, pool: &PgPool) -> Result<Option<Value>> {
10399
let path = cache_path(&language, uid);
104100

105101
if PathBuf::from(&path).exists() {
@@ -119,30 +115,27 @@ pub async fn get(uid: i32, language: Language, pool: &PgPool) -> Result<Value> {
119115
if should_update {
120116
update_and_get(uid, language, pool).await
121117
} else {
122-
Ok(cached_json)
118+
Ok(Some(cached_json))
123119
}
124120
} else {
125121
update_and_get(uid, language, pool).await
126122
}
127123
}
128124

129-
pub async fn update_and_get(uid: i32, language: Language, pool: &PgPool) -> Result<Value> {
125+
pub async fn update_and_get(uid: i32, language: Language, pool: &PgPool) -> Result<Option<Value>> {
130126
let now = Utc::now();
131127
debug!(uid, language = %language, "mihomo update_and_get start");
132128

133129
let url = format!(
134130
"https://api.mihomo.me/sr_info_parsed/{uid}?lang={}&version=v2",
135131
language.mihomo()
136132
);
137-
debug!(uid, language = %language, url = %url, "fetching mihomo payload");
138133

139-
let mut json: Value = match fetch_json(&url, uid, language, "localized").await {
140-
Ok(json) => json,
141-
Err(err) => {
142-
warn!(uid, language = %language, url = %url, error = %err, "mihomo localized fetch failed");
143-
return Err(err);
144-
}
134+
let mut json = match fetch_json(&url, uid, language, "localized").await? {
135+
Some(json) => json,
136+
None => return Ok(None),
145137
};
138+
146139
debug!(uid, language = %language, "fetched mihomo payload");
147140
if let Some(o) = json.as_object_mut() {
148141
o.insert("updated_at".to_string(), serde_json::to_value(now)?);
@@ -155,13 +148,11 @@ pub async fn update_and_get(uid: i32, language: Language, pool: &PgPool) -> Resu
155148
let en_url = format!("https://api.mihomo.me/sr_info_parsed/{uid}?lang=en&version=v2",);
156149
debug!(uid, language = %language, url = %en_url, "fetching english mihomo payload");
157150

158-
let mut en_json: Value = match fetch_json(&en_url, uid, language, "english").await {
159-
Ok(json) => json,
160-
Err(err) => {
161-
warn!(uid, language = %language, url = %en_url, error = %err, "mihomo english fetch failed");
162-
return Err(err);
163-
}
151+
let mut en_json = match fetch_json(&en_url, uid, language, "english").await? {
152+
Some(json) => json,
153+
None => return Ok(None),
164154
};
155+
165156
debug!(uid, language = %language, "fetched english mihomo payload");
166157
if let Some(o) = en_json.as_object_mut() {
167158
o.insert("updated_at".to_string(), serde_json::to_value(now)?);
@@ -252,5 +243,5 @@ pub async fn update_and_get(uid: i32, language: Language, pool: &PgPool) -> Resu
252243
database::achievement_scores::set(&db_score_achievement, pool).await?;
253244
debug!(uid, language = %language, timestamp = %timestamp, "mihomo update_and_get complete");
254245

255-
Ok(json)
246+
Ok(Some(json))
256247
}

0 commit comments

Comments
 (0)