{"record":{"id":"1bb18592ac9efc7e","repo":"jlcodes99/cockpit-tools","slug":"url","errorCode":null,"errorMessage":"网关 {} 请求失败[{}]: {} (url={})","messagePattern":"网关 (.+?) 请求失败\\[(.+?)\\]: (.+?) \\(url=(.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/src/modules/wakeup.rs","lineNumber":749,"sourceCode":"    client: &reqwest::Client,\n    url: &str,\n    body: &serde_json::Value,\n    op_name: &str,\n    cancel_rx: Option<&watch::Receiver<bool>>,\n) -> Result<serde_json::Value, String> {\n    let resp = await_with_cancel(\n        cancel_rx,\n        client\n            .post(url)\n            .header(reqwest::header::CONTENT_TYPE, \"application/json\")\n            .json(body)\n            .send(),\n    )\n    .await?\n    .map_err(|e| {\n        let kind = classify_gateway_transport_error(&e);\n        let message = format!(\"网关 {} 请求失败[{}]: {} (url={})\", op_name, kind, e, url);\n        crate::modules::logger::log_error(&format!(\"[Wakeup] {}\", message));\n        message\n    })?;\n\n    let status = resp.status();\n    let text = await_with_cancel(cancel_rx, resp.text())\n        .await?\n        .unwrap_or_default();\n    if !status.is_success() {\n        crate::modules::logger::log_error(&format!(\n            \"[Wakeup] 网关 {} 返回错误: url={}, status={}, body_len={}, body={}\",\n            op_name,\n            url,\n            status,\n            summarize_body_len(&text),\n            truncate_log_text(&text, 512)\n        ));\n        return Err(format!(\n            \"网关 {} 返回错误: status={}, body_len={}\",","sourceCodeStart":731,"sourceCodeEnd":767,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src-tauri/src/modules/wakeup.rs#L731-L767","documentation":"post_gateway_json performs a reqwest POST to a gateway operation endpoint; when the request fails at the transport layer (send().await errors) it is classified via classify_gateway_transport_error and wrapped as '网关 {op} 请求失败[{kind}]: {err} (url={url})'. This is a request never got a valid HTTP response — DNS, connect, TLS, or timeout-level failure.","triggerScenarios":"trigger_wakeup_via_client_gateway_once → post_gateway_json with an unreachable gateway host, refused connection, TLS failure, or client timeout before a response arrives.","commonSituations":"Gateway offline or wrong base URL configured; local network/VPN/proxy blocking the host; DNS resolution failure; TLS cert expired or self-signed; corporate firewall; server overloaded refusing connections.","solutions":["Check the [kind] in the message (dns/connect/tls/timeout) to target the fix","Verify the gateway URL/base configuration is correct and reachable (curl the url)","Check local network: VPN, proxy, firewall, DNS settings","Retry — the caller chain supports fallback base URLs and retry attempts","If TLS-related, update/repair CA certificates or fix the gateway's certificate"],"exampleFix":"// before\n.map_err(|e| {\n    let kind = classify_gateway_transport_error(&e);\n    let message = format!(\"网关 {} 请求失败[{}]: {} (url={})\", op_name, kind, e, url);\n    crate::modules::logger::log_error(&format!(\"[Wakeup] {}\", message));\n    message\n})?;\n// after\n.map_err(|e| {\n    let kind = classify_gateway_transport_error(&e);\n    let message = format!(\"网关 {} 请求失败[{}]: {} (url={})\", op_name, kind, e, url);\n    crate::modules::logger::log_error(&format!(\"[Wakeup] {}\", message));\n    if matches!(kind, TransportErrorKind::Timeout | TransportErrorKind::Connect) {\n        // caller falls back to next base URL\n    }\n    message\n})?;","handlingStrategy":"retry","validationCode":"// Reachability pre-check before posting to the gateway\nfn gateway_reachable(url: &str) -> bool {\n    reqwest::blocking::get(url).map(|r| r.status().is_success()).unwrap_or(false)\n}\nif !gateway_reachable(&gateway_base) { eprintln!(\"gateway unreachable: {}\", gateway_base); }","typeGuard":"fn is_gateway_transport_error(err: &str) -> bool { err.contains(\"请求失败[\") }","tryCatchPattern":"match trigger_wakeup_via_client_gateway(req).await {\n    Err(e) if e.contains(\"请求失败[\") => {\n        // transport-level: exponential backoff, then try next base URL\n        for base in fallback_base_urls() {\n            if try_wakeup(base).await.is_ok() { break; }\n        }\n    }\n    other => handle(other),\n}","preventionTips":["Configure multiple fallback base URLs and rotate on transport failure","Set explicit, generous connect/read timeouts on the reqwest client","Validate gateway URLs at startup with a health check","Monitor VPN/proxy state in corporate environments"],"tags":["network","gateway","http-client","reqwest"],"backgroundTag":"gateway-request-transport-failed","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}