@@ -7,7 +7,7 @@ use serde_json::Value;
77use sqlx:: PgPool ;
88use utoipa:: ToSchema ;
99
10- use anyhow:: Result ;
10+ use anyhow:: { bail , Context , Result } ;
1111
1212use crate :: { database, Language } ;
1313
@@ -50,6 +50,55 @@ 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 > {
54+ let response = reqwest:: get ( url)
55+ . await
56+ . with_context ( || format ! ( "{label} request failed for uid {uid} language {language}" ) ) ?;
57+
58+ let status = response. status ( ) ;
59+ if !status. is_success ( ) {
60+ let body = response. text ( ) . await . unwrap_or_default ( ) ;
61+ warn ! (
62+ uid,
63+ language = %language,
64+ url = %url,
65+ status = %status,
66+ body = %body,
67+ label,
68+ "response was not successful"
69+ ) ;
70+ bail ! (
71+ "{label} request returned non-success status {status} for uid {uid} language {language}"
72+ ) ;
73+ }
74+
75+ let text = response
76+ . text ( )
77+ . await
78+ . with_context ( || format ! ( "mihomo {label} body read failed for uid {uid} language {language}" ) ) ?;
79+
80+ match serde_json:: from_str ( & text) {
81+ Ok ( json) => Ok ( json) ,
82+ Err ( err) => {
83+ warn ! (
84+ uid,
85+ language = %language,
86+ url = %url,
87+ status = %status,
88+ body = %text,
89+ label,
90+ error = %err,
91+ "response decode failed"
92+ ) ;
93+ Err ( err) . with_context ( || {
94+ format ! (
95+ "{label} json decode failed for uid {uid} language {language} status {status}"
96+ )
97+ } )
98+ }
99+ }
100+ }
101+
53102pub async fn get ( uid : i32 , language : Language , pool : & PgPool ) -> Result < Value > {
54103 let path = cache_path ( & language, uid) ;
55104
@@ -79,23 +128,41 @@ pub async fn get(uid: i32, language: Language, pool: &PgPool) -> Result<Value> {
79128
80129pub async fn update_and_get ( uid : i32 , language : Language , pool : & PgPool ) -> Result < Value > {
81130 let now = Utc :: now ( ) ;
131+ debug ! ( uid, language = %language, "mihomo update_and_get start" ) ;
82132
83133 let url = format ! (
84134 "https://api.mihomo.me/sr_info_parsed/{uid}?lang={}&version=v2" ,
85135 language. mihomo( )
86136 ) ;
137+ debug ! ( uid, language = %language, url = %url, "fetching mihomo payload" ) ;
87138
88- let mut json: Value = reqwest:: get ( & url) . await ?. json ( ) . await ?;
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+ }
145+ } ;
146+ debug ! ( uid, language = %language, "fetched mihomo payload" ) ;
89147 if let Some ( o) = json. as_object_mut ( ) {
90148 o. insert ( "updated_at" . to_string ( ) , serde_json:: to_value ( now) ?) ;
91149 }
92150
93151 let ( en_json, is_english) = if language == Language :: En {
152+ debug ! ( uid, language = %language, "using fetched payload as english payload" ) ;
94153 ( json. clone ( ) , true )
95154 } else {
96155 let en_url = format ! ( "https://api.mihomo.me/sr_info_parsed/{uid}?lang=en&version=v2" , ) ;
156+ debug ! ( uid, language = %language, url = %en_url, "fetching english mihomo payload" ) ;
97157
98- let mut en_json: Value = reqwest:: get ( & en_url) . await ?. json ( ) . await ?;
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+ }
164+ } ;
165+ debug ! ( uid, language = %language, "fetched english mihomo payload" ) ;
99166 if let Some ( o) = en_json. as_object_mut ( ) {
100167 o. insert ( "updated_at" . to_string ( ) , serde_json:: to_value ( now) ?) ;
101168 }
@@ -108,6 +175,9 @@ pub async fn update_and_get(uid: i32, language: Language, pool: &PgPool) -> Resu
108175 let writer = brotli:: CompressorWriter :: new ( file, 4096 , 4 , 22 ) ;
109176
110177 serde_json:: to_writer ( writer, & json) ?;
178+ debug ! ( uid, language = %language, "cached mihomo payload" ) ;
179+ } else {
180+ debug ! ( uid, language = %language, "skipped caching localized mihomo payload" ) ;
111181 }
112182
113183 if !is_english && serde_json:: from_value :: < Mihomo > ( en_json. clone ( ) ) . is_ok ( ) {
@@ -116,6 +186,9 @@ pub async fn update_and_get(uid: i32, language: Language, pool: &PgPool) -> Resu
116186 let writer = brotli:: CompressorWriter :: new ( file, 4096 , 4 , 22 ) ;
117187
118188 serde_json:: to_writer ( writer, & en_json) ?;
189+ debug ! ( uid, language = %language, "cached english mihomo payload" ) ;
190+ } else if !is_english {
191+ debug ! ( uid, language = %language, "skipped caching english mihomo payload" ) ;
119192 }
120193
121194 let mihomo: Mihomo = serde_json:: from_value ( en_json) ?;
@@ -177,6 +250,7 @@ pub async fn update_and_get(uid: i32, language: Language, pool: &PgPool) -> Resu
177250 } ;
178251
179252 database:: achievement_scores:: set ( & db_score_achievement, pool) . await ?;
253+ debug ! ( uid, language = %language, timestamp = %timestamp, "mihomo update_and_get complete" ) ;
180254
181255 Ok ( json)
182256}
0 commit comments