{"record":{"id":"97a54e03362c958a","repo":"tonhowtf/omniget","slug":"pinterest-respondeu-http-sem-json","errorCode":null,"errorMessage":"Pinterest respondeu HTTP {} sem JSON ({})","messagePattern":"Pinterest respondeu HTTP (.+?) sem JSON \\((.+?)\\)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pinterest/api.rs","lineNumber":895,"sourceCode":"        let mut attempt = 0u32;\n        loop {\n            attempt += 1;\n            let req = self\n                .http\n                .get(&url)\n                .query(&[(\"source_url\", source_url), (\"data\", data.as_str())])\n                .header(\"X-Pinterest-Source-Url\", source_url);\n            let resp = self.apply_cookie(req).send().await?;\n            let status = resp.status();\n            if (status.as_u16() == 429 || status.is_server_error()) && attempt < 4 {\n                tokio::time::sleep(Duration::from_millis(800 * attempt as u64 * attempt as u64))\n                    .await;\n                continue;\n            }\n            let body: Value = match resp.json().await {\n                Ok(v) => v,\n                Err(e) => {\n                    return Err(anyhow!(\n                        \"Pinterest respondeu HTTP {} sem JSON ({})\",\n                        status,\n                        e\n                    ))\n                }\n            };\n            let rr = &body[\"resource_response\"];\n            if rr[\"status\"].as_str() != Some(\"success\") {\n                let msg = rr[\"message\"]\n                    .as_str()\n                    .or_else(|| rr[\"error\"][\"message\"].as_str())\n                    .unwrap_or(\"resposta sem status de sucesso\");\n                let code = rr[\"error\"][\"http_status\"]\n                    .as_u64()\n                    .unwrap_or(status.as_u16() as u64);\n                if code == 404 {\n                    return Err(anyhow!(\n                        \"nao encontrado no Pinterest (privado, removido ou URL errada): {}\",","sourceCodeStart":877,"sourceCodeEnd":913,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pinterest/api.rs#L877-L913","documentation":"The Pinterest API client received an HTTP response whose status was handled as an error, but the body could not be deserialized into JSON (resp.json() failed). The message includes the HTTP status and the deserialization error, indicating Pinterest answered with non-JSON content (HTML error page, empty body, gateway noise) on a non-success path.","triggerScenarios":"Hitting a Pinterest endpoint during an error condition (rate limiting, outage, proxy intercept) so the server returns an HTML/empty body instead of JSON, with a non-OK status.","commonSituations":"Corporate proxies or CAPTCHA/challenge pages returning HTML; Pinterest 5xx outages returning plain-text error pages; auth failures returning empty bodies; VPN/datacenter IPs blocked by Pinterest's WAF.","solutions":["Log the raw response text on parse failure to see what Pinterest actually returned.","Retry with backoff — these bodies usually accompany transient 5xx/challenge responses.","Ensure requests include proper headers (User-Agent, auth cookies/token) so Pinterest returns JSON error payloads.","Route the request through a residential/proper egress IP if a datacenter IP is triggering WAF HTML pages."],"exampleFix":"// before\nlet body: Value = resp.json().await?;\n// after\nlet text = resp.text().await?;\nlet body: Value = serde_json::from_str(&text)\n    .with_context(|| format!(\"non-JSON response ({}): {}\", status, &text[..text.len().min(200)]))?;","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match fetch() {\n    Err(e) if e.to_string().contains(\"sem JSON\") => {\n        // transient HTML/challenge/5xx body: back off and retry\n        tokio::time::sleep(backoff).await;\n        retry();\n    }\n    other => other?,\n}","preventionTips":["Send browser-like headers (User-Agent, Accept) so Pinterest returns JSON error payloads.","Add exponential backoff with jitter for transient non-JSON responses.","Avoid datacenter egress IPs that trigger WAF HTML challenge pages.","Log raw response bodies on parse failure for diagnostics."],"tags":["pinterest","http","json","network"],"backgroundTag":"invalid-json-response","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}