From b690bf2761ae00efd01cf5fc98d2086151a7d256 Mon Sep 17 00:00:00 2001 From: Jocelyn Castellano Date: Fri, 31 Oct 2025 23:56:29 -0500 Subject: [PATCH] Retry 429s after waiting a specified time --- packages/app-lib/src/util/fetch.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/app-lib/src/util/fetch.rs b/packages/app-lib/src/util/fetch.rs index fafba22152..e4d5f209b0 100644 --- a/packages/app-lib/src/util/fetch.rs +++ b/packages/app-lib/src/util/fetch.rs @@ -10,9 +10,9 @@ use serde::de::DeserializeOwned; use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::sync::LazyLock; -use std::time::{self}; +use std::time::{self, Duration}; use tokio::sync::Semaphore; -use tokio::{fs::File, io::AsyncWriteExt}; +use tokio::{fs::File, io::AsyncWriteExt, time::sleep}; #[derive(Debug)] pub struct IoSemaphore(pub Semaphore); @@ -116,6 +116,16 @@ pub async fn fetch_advanced( || resp.status().is_server_error() { let backup_error = resp.error_for_status_ref().unwrap_err(); + if resp.status() == 429 + && let Some(reset_header) = + resp.headers().get("X-Ratelimit-Reset") + && let Ok(seconds) = reset_header.to_str() + && let Ok(seconds) = seconds.parse::() + && attempt <= FETCH_ATTEMPTS + { + sleep(Duration::from_secs(seconds)).await; + continue; + } if let Ok(error) = resp.json().await { return Err(ErrorKind::LabrinthError(error).into()); }