tonhowtf/omniget · error

o Pinterest nao devolveu esse pin

Error message

o Pinterest nao devolveu esse pin

What it means

api.rs fetches a pin via Pinterest's internal PinResource endpoint and parses the JSON into a Pin struct. When `parse_pin(&data)` returns None — i.e. the response lacked the fields expected for a "detailed" pin — the library raises this anyhow error instead of returning a partial object. It is the library's way of surfacing "Pinterest answered, but the pin is not available" (deleted, private, region-blocked, or anti-bot page returned).

Solutions

  1. Verify the pin id (long numeric id) is still live by opening https://pinterest.com/pin/<id>/ in a browser.
  2. Refresh/explicitly set session cookies on the client so Pinterest returns real JSON instead of a login page.
  3. Add backoff/retry — transient anti-bot responses cause spurious parse failures.
  4. Treat as not-found: catch the error and skip the pin rather than failing the whole batch.

Example fix

// before
let pin = api.pin(&stale_id).await?;
// after
let pin = match api.pin(&stale_id).await {
    Ok(p) => p,
    Err(e) if e.to_string().contains("nao devolveu") => { skip(stale_id); continue; }
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: try-catch

Validate before calling

// Pin ids are long numeric strings
fn is_plausible_pin_id(id: &str) -> bool { !id.is_empty() && id.chars().all(|c| c.is_ascii_digit()) && id.len() >= 10 }

Type guard

fn pin_is_fetchable(pin: &Option<Pin>) -> bool { pin.is_some() }

Try / catch

match api.pin(&id).await {
    Ok(p) => process(p),
    Err(e) if e.to_string().contains("nao devolveu esse pin") => mark_deleted(&id),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling PinterestApi::pin(id) when the id does not exist, was deleted, is in a secret/private board, or when Pinterest returns an HTML challenge/login page instead of PinResource JSON, making parse_pin fail.

Common situations: Stale pin ids saved in a database; scraping pins from another user's secret board; Pinterest serving unauthenticated/limited responses after rate limiting or cookie expiry.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/pinterest/api.rs:944

                .as_array()
                .and_then(|a| a.first())
                .and_then(|b| b.as_str())
                .map(|b| b.to_string())
                .or_else(|| rr["bookmark"].as_str().map(|b| b.to_string()))
                .filter(|b| b != "-end-" && !b.starts_with("Y2JOb25lO"));
            return Ok((rr["data"].clone(), bookmark));
        }
    }

    pub async fn pin(&self, id: &str) -> anyhow::Result<Pin> {
        let (data, _) = self
            .resource(
                "Pin",
                json!({ "id": id, "field_set_key": "detailed" }),
                &format!("/pin/{}/", id),
            )
            .await?;
        parse_pin(&data).ok_or_else(|| anyhow!("o Pinterest nao devolveu esse pin"))
    }

    pub async fn board(&self, user: &str, slug: &str) -> anyhow::Result<Board> {
        let src = format!("/{}/{}/", user, slug);
        let (data, _) = self
            .resource(
                "Board",
                json!({ "username": user, "slug": slug, "field_set_key": "detailed" }),
                &src,
            )
            .await?;
        parse_board(&data).ok_or_else(|| anyhow!("board nao encontrado"))
    }

    pub async fn board_sections(&self, board_id: &str) -> anyhow::Result<Vec<Section>> {
        let mut out = Vec::new();
        let mut bookmark: Option<String> = None;
        loop {

View on GitHub (pinned to 8600b91f42)