{"record":{"id":"4646dfdd33bd1bce","repo":"tonhowtf/omniget","slug":"tabela-de-precos-indisponivel","errorCode":null,"errorMessage":"tabela de precos indisponivel: {}","messagePattern":"tabela de precos indisponivel: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pricing.rs","lineNumber":79,"sourceCode":"        Ok(resp) if resp.status().is_success() => {\n            let text = resp.text().await?;\n            let v: serde_json::Value = serde_json::from_str(&text)?;\n            if let Some(parent) = path.parent() {\n                std::fs::create_dir_all(parent)?;\n            }\n            tokio::fs::write(&path, &text).await?;\n            Ok(v)\n        }\n        other => {\n            // Sem rede: usa o que tiver em disco, mesmo velho.\n            if let Ok(text) = tokio::fs::read_to_string(&path).await {\n                if let Ok(v) = serde_json::from_str(&text) {\n                    return Ok(v);\n                }\n            }\n            match other {\n                Ok(r) => Err(anyhow!(\"tabela de precos: HTTP {}\", r.status())),\n                Err(e) => Err(anyhow!(\"tabela de precos indisponivel: {}\", e)),\n            }\n        }\n    }\n}\n\nfn per_m(v: &serde_json::Value, key: &str) -> Option<f64> {\n    v.get(key).and_then(|x| x.as_f64()).map(|x| x * 1_000_000.0)\n}\n\nfn to_price(key: &str, v: &serde_json::Value) -> ModelPrice {\n    ModelPrice {\n        key: key.to_string(),\n        provider: v[\"litellm_provider\"].as_str().unwrap_or(\"\").to_string(),\n        mode: v[\"mode\"].as_str().unwrap_or(\"\").to_string(),\n        input_per_m: per_m(v, \"input_cost_per_token\"),\n        output_per_m: per_m(v, \"output_cost_per_token\"),\n        cache_read_per_m: per_m(v, \"cache_read_input_token_cost\"),\n        cache_write_per_m: per_m(v, \"cache_creation_input_token_cost\"),","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pricing.rs#L61-L97","documentation":"load() falls back to a network fetch when the cache is missing/stale; if that fetch fails at the transport layer (connection refused, DNS failure, timeout, TLS error), the underlying reqwest error is wrapped as \"tabela de precos indisponivel: {}\". It means the price table could not be obtained from either cache or network.","triggerScenarios":"Calling info/search/price_for with an unreadable cache AND the remote pricing service being unreachable — no network, DNS failure, server down, TLS handshake failure, or connection timeout.","commonSituations":"Offline development machine, pricing endpoint permanently shut down, firewall blocking outbound HTTPS, expired TLS certs on the upstream host.","solutions":["Read the wrapped inner error to distinguish DNS vs connection vs TLS failure","Restore network connectivity or fix DNS/proxy settings","Populate the cache file manually (place a valid JSON price table at cache_path) so load() succeeds without network","Retry when the upstream service is back online"],"exampleFix":"// pre-seed the cache to avoid needing the network\n// $XDG_DATA_HOME/omniget/pricing.json\n{\"gpt-4o\": {\"input_per_m\": 2.5, \"output_per_m\": 10.0}}","handlingStrategy":"fallback","validationCode":"// reachability probe before calling\nlet reachable = reqwest::get(\"https://raw.githubusercontent.com\").await.is_ok();","typeGuard":null,"tryCatchPattern":"match pricing::search(\"gpt-4o\", \"\", 10).await {\n    Err(e) if e.to_string().contains(\"indisponivel\") => {\n        eprintln!(\"sem rede; use valores padrão ou cache local\");\n        default_prices()\n    }\n    other => other?,\n}","preventionTips":["Keep a seeded local cache of the price table for offline use","Distinguish transport errors from HTTP-status errors in your retry policy","Check connectivity/DNS before assuming the service is down"],"tags":["network","connection","pricing","rust"],"backgroundTag":"api-request-failed","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"}