tonhowtf/omniget · error

Erro da API

Error message

Erro da API: {}

What it means

Catch-all branch in fetch_post's error match: the Bluesky API returned an error envelope with an unrecognized error string, so it is propagated verbatim as "Erro da API: {error}". It signals an error type the mapping does not explicitly handle.

Solutions

  1. Read the appended error string to identify the actual API error code.
  2. Add an explicit match arm for any recurring error code to give a better message.
  3. Retry via the yt-dlp fallback path in get_media_info if native fetching keeps failing.
  4. Check Bluesky API status/changelog if a new error code appears en masse.

Example fix

// before
_ => Err(anyhow!("Erro da API: {}", error)),
// after
"ExpiredToken" | "InvalidTokenError" => Err(anyhow!("Authentication required")),
other => Err(anyhow!("Erro da API: {}", other)),
Defensive patterns

Strategy: try-catch

Try / catch

match downloader.get_media_info(url).await {
    Err(e) if e.to_string().starts_with("Erro da API:") => {
        let code = e.to_string().trim_start_matches("Erro da API: ").to_string();
        log::warn!("unmapped bluesky API error: {}", code);
        // try yt-dlp fallback or surface code to user
    }
    other => other.map(|i| download(i)),
}

Prevention

When it happens

Trigger: Bluesky's AppView returns error codes beyond NotFound/InternalServerError/InvalidRequest, e.g. "InvalidTokenError", "AuthRequiredError", or new error kinds introduced server-side.

Common situations: New Bluesky API error codes after API evolution, authentication-gated content on public.api.bsky.app, or unusual server responses during incidents.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/bdec5a8949341db6. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/bluesky.rs:148

        let url = format!(
            "{}?depth=0&parentHeight=0&uri={}",
            API_BASE,
            urlencoding::encode(&uri)
        );

        let response = self.client.get(&url).send().await?;

        if !response.status().is_success() {
            return Err(anyhow!("Bluesky API retornou HTTP {}", response.status()));
        }

        let json: serde_json::Value = response.json().await?;

        if let Some(error) = json.get("error").and_then(|e| e.as_str()) {
            return match error {
                "NotFound" | "InternalServerError" => Err(anyhow!("Post not available")),
                "InvalidRequest" => Err(anyhow!("Unsupported link")),
                _ => Err(anyhow!("Erro da API: {}", error)),
            };
        }

        Ok(json)
    }
}

enum BlueskyMedia {
    Video { hls_url: String },
    Images { urls: Vec<String> },
    Gif { url: String },
}

fn extract_media(embed: &serde_json::Value) -> Option<BlueskyMedia> {
    let embed_type = embed.get("$type")?.as_str()?;

    match embed_type {
        "app.bsky.embed.video#view" => {

View on GitHub (pinned to 8600b91f42)