tonhowtf/omniget · error
SponsorBlock: HTTP
Error message
SponsorBlock: HTTP {} What it means
Thrown when the SponsorBlock API returns a non-OK (non-2xx) HTTP status to the segments query. The error embeds the response's status code so the caller can distinguish 404 (no video), 429 (rate limit), 5xx (server trouble), etc.
Solutions
- Read the embedded status code and handle 429 by waiting/backing off before retrying.
- Retry 5xx errors after a delay — they are usually transient server-side issues.
- Verify the categories list and request shape match the SponsorBlock API contract if status is 400.
- Check SponsorBlock service status (status.sponsor.ajay.app) during outages.
Defensive patterns
Strategy: retry
Try / catch
match sponsorblock::segments(&video, &cats).await {
Ok(s) => use(s),
Err(e) if e.to_string().contains("HTTP 429") => {
tokio::time::sleep(Duration::from_secs(30)).await;
// retry once
}
Err(e) => log::warn("sponsorblock unavailable: {e}"),
} Prevention
- Back off on 429 — SponsorBlock rate limits per user ID.
- Treat 5xx as transient and retry with delay.
- Check SponsorBlock status page during outages.
- Cache segment results per video to reduce request volume.
When it happens
Trigger: Calling `sponsorblock::segments` when the SponsorBlock server replies with an error status: network/proxy issues surfacing as 5xx, per-account rate limiting (429), or an unexpected request the API rejects.
Common situations: Submitting queries too fast (SponsorBlock rate limits per user ID); SponsorBlock API downtime or maintenance; a proxy/firewall returning error pages; invalid categories parameter causing 400.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/0f5cea627880d2e5.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/sponsorblock.rs:102
let client = super::client()?;
let resp = client.get(&url).send().await?;
let mut segs: Vec<Segment> = Vec::new();
if resp.status().as_u16() == 404 {
// sem segmentos para esse prefixo
} else if resp.status().is_success() {
let arr: Vec<serde_json::Value> = resp.json().await?;
for v in arr {
if v["videoID"].as_str() == Some(id.as_str()) {
if let Some(list) = v["segments"].as_array() {
segs.extend(
list.iter()
.filter_map(|s| serde_json::from_value(s.clone()).ok()),
);
}
}
}
} else {
return Err(anyhow!("SponsorBlock: HTTP {}", resp.status()));
}
segs.sort_by(|a, b| {
a.segment[0]
.partial_cmp(&b.segment[0])
.unwrap_or(std::cmp::Ordering::Equal)
});
let skipped: f64 = segs
.iter()
.filter(|s| s.action_type == "skip" || s.action_type.is_empty())
.map(|s| (s.segment[1] - s.segment[0]).max(0.0))
.sum();
let mut used: Vec<&str> = segs
.iter()
.filter(|s| s.action_type != "chapter" && s.action_type != "poi")
.map(|s| s.category.as_str())
.collect();
used.sort();
used.dedup();View on GitHub (pinned to 8600b91f42)