tonhowtf/omniget · error · anyhow

o Trakt não devolveu o código do dispositivo

Error message

o Trakt não devolveu o código do dispositivo

What it means

Thrown by parse_device_code when the JSON returned by Trakt's device/code endpoint lacks a non-empty device_code or user_code field. These two values are mandatory to drive the device flow (polling token + code the user enters), so their absence makes the response unusable.

Solutions

  1. Log the raw response body from /oauth/device/code and inspect its shape
  2. Verify the request hit the real Trakt API (no proxy/interceptor altering the body)
  3. Retry the request — transient gateway responses can masquerade as success
  4. If Trakt changed the field names, update parse_device_code accordingly

Example fix

// before
let v: Value = r.json().await?;
parse_device_code(&v)
// after
let v: Value = r.json().await?;
if v.get("device_code").is_none() {
    tracing::error!("unexpected device/code body: {}", v);
}
parse_device_code(&v)
Defensive patterns

Strategy: try-catch

Validate before calling

let body = resp.text().await?;
let v: serde_json::Value = serde_json::from_str(&body)?;
if v.get("device_code").and_then(|x| x.as_str()).map_or(true, str::is_empty) {
    // log body and abort before parsing into DeviceCode
}

Type guard

fn has_device_code(v: &serde_json::Value) -> bool {
    v.get("device_code").and_then(|x| x.as_str()).map_or(false, |s| !s.is_empty())
}

Try / catch

match device_code().await {
    Err(e) if e.to_string().contains("não devolveu o código") => {
        tracing::error!("unexpected Trakt device/code response");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Trakt returned a success status but the body is missing device_code or user_code — e.g. an unexpected JSON shape, an error object with 200 semantics, or an empty/error body parsed as JSON.

Common situations: API changes on Trakt's side, a proxy/captive portal returning HTML or JSON without the fields, mocking/testing with incomplete fixtures (note the test codigo_do_dispositivo_tem_padrao_quando_falta_campo covers optional-field defaults, but device/user codes remain mandatory).

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/lists/trakt.rs:266

            r.status()
        ));
    }
    let v: Value = r.json().await?;
    parse_device_code(&v)
}

pub fn parse_device_code(v: &Value) -> Result<DeviceCode> {
    let s = |k: &str| {
        v.get(k)
            .and_then(|x| x.as_str())
            .unwrap_or_default()
            .to_string()
    };
    let n = |k: &str, d: u64| v.get(k).and_then(|x| x.as_u64()).unwrap_or(d);
    let device = s("device_code");
    let user = s("user_code");
    if device.is_empty() || user.is_empty() {
        return Err(anyhow!("o Trakt não devolveu o código do dispositivo"));
    }
    let mut url = s("verification_url");
    if url.is_empty() {
        url = "https://trakt.tv/activate".to_string();
    }
    Ok(DeviceCode {
        device_code: device,
        user_code: user,
        verification_url: url,
        expires_in: n("expires_in", 600),
        // O Trakt pede 5 s; menos que isso leva 429.
        interval: n("interval", 5).clamp(1, 60),
    })
}

#[derive(Debug, Clone, Serialize)]
pub struct ConnectResult {
    pub connected: bool,

View on GitHub (pinned to 8600b91f42)