feat: auto-retry uploads when rate limited (v0.13.0)
Backend: rate limiter gains check_with_retry() returning seconds until the next slot opens. Upload 429 responses include retry_after_secs in JSON and a Retry-After header. Frontend: upload queue catches 429 as RateLimitError, resets affected item to pending, schedules processQueue() for the server-reported delay, and shows a live countdown banner in the queue UI. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -180,9 +180,7 @@ pub async fn download_zip(
|
||||
let ip = client_ip(&headers, "unknown");
|
||||
let limit = get_config_usize(&state.pool, "export_rate_per_day", 3).await;
|
||||
if !state.rate_limiter.check(format!("export:{ip}"), limit, Duration::from_secs(86400)) {
|
||||
return Err(AppError::TooManyRequests(
|
||||
"Zu viele Anfragen. Bitte warte kurz und versuche es erneut.".into(),
|
||||
));
|
||||
return Err(AppError::TooManyRequests("Zu viele Anfragen. Bitte warte kurz und versuche es erneut.".into(), None));
|
||||
}
|
||||
|
||||
let event = crate::models::event::Event::find_by_slug(&state.pool, &state.config.event_slug)
|
||||
@@ -211,9 +209,7 @@ pub async fn download_html(
|
||||
let ip = client_ip(&headers, "unknown");
|
||||
let limit = get_config_usize(&state.pool, "export_rate_per_day", 3).await;
|
||||
if !state.rate_limiter.check(format!("export:{ip}"), limit, Duration::from_secs(86400)) {
|
||||
return Err(AppError::TooManyRequests(
|
||||
"Zu viele Anfragen. Bitte warte kurz und versuche es erneut.".into(),
|
||||
));
|
||||
return Err(AppError::TooManyRequests("Zu viele Anfragen. Bitte warte kurz und versuche es erneut.".into(), None));
|
||||
}
|
||||
|
||||
let event = crate::models::event::Event::find_by_slug(&state.pool, &state.config.event_slug)
|
||||
|
||||
Reference in New Issue
Block a user