@@ -172,7 +172,7 @@ impl BundleTankopedia {
172172 parameters_path : PathBuf ,
173173 vehicle_tag : String ,
174174 ) -> Result < Option < ( VehicleJsonDetails , DynamicImage ) > > {
175- info ! ( "📤 Retrieving…" ) ;
175+ info ! ( "📤 Retrieving details …" ) ;
176176 let response = client
177177 . get ( format ! ( "https://eu.wotblitz.com/en/api/tankopedia/vehicle/{vehicle_tag}/" ) )
178178 . send ( )
@@ -183,18 +183,25 @@ impl BundleTankopedia {
183183 return Ok ( None ) ;
184184 }
185185 let details: VehicleJsonDetails = response
186+ . error_for_status ( ) ?
186187 . json ( )
187188 . await
188189 . with_context ( || format ! ( "failed to deserialize vehicle `{vehicle_tag}`" ) ) ?;
189190 let image = {
190191 // First, try to request the image from the API.
191- let response = client. get ( & details. image_url ) . send ( ) . await ?;
192- if response. status ( ) == StatusCode :: OK {
193- let raw = response. bytes ( ) . await ?;
194- Some ( image:: io:: Reader :: new ( Cursor :: new ( raw) ) . with_guessed_format ( ) ?. decode ( ) ?)
192+ if let Ok ( image) = Self :: fetch_image ( client, & details. image_url ) . await {
193+ Some ( image)
194+ } else if let Ok ( image) = {
195+ // Yeah, sometimes they return non-existing URLs. Crazy, huh? Try some guess-work.
196+ let guessed_url = format ! (
197+ "https://glossary-eu-static.gcdn.co/icons/wotb/latest/uploaded/vehicles/hd/{vehicle_tag}.png"
198+ ) ;
199+ Self :: fetch_image ( client, & guessed_url) . await
200+ } {
201+ warn ! ( failed_url = details. image_url, "⚠️ Succeeded with the guessed URL" ) ;
202+ Some ( image)
195203 } else {
196- // Yeah, sometimes they return non-existing URLs. Crazy, huh?
197- warn ! ( "⚠️ Falling back to the client icon" ) ;
204+ warn ! ( details. image_url, "⚠️ Falling back to the client icon" ) ;
198205 let dvpl =
199206 Dvpl :: read ( parameters_path. join ( & vehicle_tag) . with_extension ( "yaml.dvpl" ) )
200207 . await ?;
@@ -210,6 +217,17 @@ impl BundleTankopedia {
210217 Ok ( Some ( ( details, image) ) )
211218 }
212219
220+ #[ instrument( skip_all, fields( url = url) ) ]
221+ async fn fetch_image ( client : & Client , url : & str ) -> Result < DynamicImage > {
222+ let response = client. get ( url) . send ( ) . await ?;
223+ if response. status ( ) == StatusCode :: OK {
224+ let raw = response. bytes ( ) . await ?;
225+ Ok ( image:: io:: Reader :: new ( Cursor :: new ( raw) ) . with_guessed_format ( ) ?. decode ( ) ?)
226+ } else {
227+ bail ! ( "failed to fetch the image from {url} ({})" , response. status( ) ) ;
228+ }
229+ }
230+
213231 /// Extract the vehicle icon from the game client.
214232 ///
215233 /// # Parameters
0 commit comments