{"record":{"id":"11fa83886b0370d4","repo":"BigPizzaV3/CodexPlusPlus","slug":"error-11fa83","errorCode":null,"errorMessage":"下载安装包失败：{error}","messagePattern":"下载安装包失败：(.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/update.rs","lineNumber":222,"sourceCode":"        .as_ref()\n        .ok_or_else(|| anyhow::anyhow!(\"没有可下载的 Release asset\"))?;\n    let _ = crate::diagnostic_log::append_diagnostic_log(\n        \"update.perform.start\",\n        json!({\n            \"version\": release.version,\n            \"assetName\": release.asset_name,\n            \"assetUrl\": url,\n            \"downloadTimeoutSeconds\": UPDATE_DOWNLOAD_TIMEOUT.as_secs()\n        }),\n    );\n    let response = match update_http_client()?.get(url).send().await {\n        Ok(response) => response,\n        Err(error) => {\n            let _ = crate::diagnostic_log::append_diagnostic_log(\n                \"update.download.failed\",\n                json!({ \"version\": release.version, \"assetName\": release.asset_name, \"error\": error.to_string() }),\n            );\n            return Err(anyhow::anyhow!(\"下载安装包失败：{error}\"));\n        }\n    };\n    let response = match response.error_for_status() {\n        Ok(response) => response,\n        Err(error) => {\n            let _ = crate::diagnostic_log::append_diagnostic_log(\n                \"update.download.bad_status\",\n                json!({ \"version\": release.version, \"assetName\": release.asset_name, \"error\": error.to_string() }),\n            );\n            return Err(anyhow::anyhow!(\"下载安装包失败：{error}\"));\n        }\n    };\n    let bytes = match response.bytes().await {\n        Ok(bytes) => bytes,\n        Err(error) => {\n            let _ = crate::diagnostic_log::append_diagnostic_log(\n                \"update.download.body_failed\",\n                json!({ \"version\": release.version, \"assetName\": release.asset_name, \"error\": error.to_string() }),","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/1f431ae49b57b3055e0e6845ba6156c6b4232b4d/crates/codex-plus-core/src/update.rs#L204-L240","documentation":"perform_update downloads the asset via update_http_client()?.get(url).send().await; if reqwest cannot complete the request at all, the reqwest error is wrapped as \"下载安装包失败：{error}\" and logged to the diagnostic log under update.download.failed. This is transport-level failure (DNS, TCP connect, TLS handshake, proxy error, request timeout), distinct from the later HTTP-status and body-read stages.","triggerScenarios":"Machine offline or DNS broken when the update starts; HTTPS_PROXY/ALL_PROXY pointing at a dead proxy; TLS interception rejecting the CDN certificate; the connection phase exceeding UPDATE_DOWNLOAD_TIMEOUT.","commonSituations":"Corporate networks blocking GitHub Releases / object-storage CDNs; VPN split-tunneling dropping the CDN domain; containers without proxy env vars configured; captive portals.","solutions":["Check basic connectivity to the asset URL (curl -I <asset_url>)","Fix or unset HTTP_PROXY/HTTPS_PROXY/ALL_PROXY if the proxy is unreachable","Retry after restoring network/DNS","If you build from source and consistently hit the timeout, raise UPDATE_DOWNLOAD_TIMEOUT in update.rs"],"exampleFix":"// before\nlet install = perform_update(&release, &dir).await?;\n\n// after (bounded retry for transport errors)\nlet mut last_err = None;\nfor attempt in 0..3u32 {\n    match perform_update(&release, &dir).await {\n        Ok(install) => return Ok(install),\n        Err(e) if e.to_string().contains(\"下载安装包失败\") && attempt < 2 => {\n            tokio::time::sleep(std::time::Duration::from_secs(1 << attempt)).await;\n            last_err = Some(e);\n        }\n        Err(e) => return Err(e),\n    }\n}\nErr(last_err.unwrap())","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in 0..3u32 {\n    match perform_update(&release, &dir).await {\n        Ok(install) => return Ok(install),\n        Err(e) if e.to_string().contains(\"下载安装包失败\") && attempt < 2 => {\n            tokio::time::sleep(std::time::Duration::from_secs(1 << attempt)).await;\n        }\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["Verify connectivity to the asset host before entering an update flow","Keep HTTP(S)_PROXY env vars correct in containers and packaged apps","Size UPDATE_DOWNLOAD_TIMEOUT to your slowest supported link when building from source"],"tags":["network","download","proxy","timeout","update"],"backgroundTag":"network-request-failed","analyzedSha":"1f431ae49b57b3055e0e6845ba6156c6b4232b4d","analyzedAt":"2026-08-16T20:54:18.598Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}