tonhowtf/omniget · error · anyhow::Error

Erro da API

Error message

Erro da API: {}

What it means

In `fetch_post` (src-tauri/src/platforms/bluesky/mod.rs:148), the AppView returned a structured error string not covered by the known cases (NotFound, InternalServerError, InvalidRequest), producing "Erro da API: {error}". This is the catch-all for any other AppView error name, present or future.

Solutions

  1. Read the error name in the message and check the AT Protocol AppView error documentation for its meaning.
  2. Add explicit handling for recurring new error names (e.g. rate limits → backoff).
  3. Check whether authentication is required for the content and configure an account if supported.
  4. Retry later if the error suggests a transient or server-side condition.

Example fix

// before
_ => Err(anyhow!("Erro da API: {}", error)),
// after
"RateLimitExceeded" => Err(anyhow!("Bluesky rate limit exceeded; retry later")),
_ => Err(anyhow!("Erro da API: {}", error)),
Defensive patterns

Strategy: try-catch

Try / catch

match fetch_post(&user, &post_id).await {
    Ok(json) => json,
    Err(e) if e.to_string().starts_with("Erro da API:") => {
        let code = e.to_string().splitn(2, ": ").nth(1).unwrap_or("");
        anyhow::bail!("Bluesky AppView returned unknown error '{code}'; check AT Protocol docs or retry later")
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: The response JSON contains an `error` field whose value is an unrecognized error name — e.g. AuthRequired, RateLimitExceeded, or newly introduced AppView error codes.

Common situations: Bluesky adding new error types the local mapping doesn't know; authentication-gated content returning AuthRequired; temporary API changes during platform migrations.

Related errors


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

Appendix: source

Thrown at src-tauri/src/platforms/bluesky/mod.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)