{"record":{"id":"e2c01fd0539b5612","repo":"janhq/jan","slug":"http-request-failed-0","errorCode":null,"errorMessage":"HTTP request failed: {0}","messagePattern":"HTTP request failed: (.+?)","errorType":"error_code","errorClass":"UpdateError","httpStatus":null,"severity":"error","filePath":"src-tauri/src/core/updater/custom_updater.rs","lineNumber":31,"sourceCode":"use reqwest::Client;\nuse serde::{Deserialize, Serialize};\nuse std::time::Duration;\nuse thiserror::Error;\n\n/// Secret key for HMAC signature\n/// - In CI: Set JAN_SIGNING_KEY environment variable at build time\n/// - In local dev: Falls back to a test key\npub(crate) const SECRET_KEY: &str = match option_env!(\"JAN_SIGNING_KEY\") {\n    Some(key) => key,\n    None => \"local-dev-test-key-not-for-production\",\n};\n\n/// Timeout for HTTP requests\nconst REQUEST_TIMEOUT_SECS: u64 = 30;\n\n#[derive(Debug, Error)]\npub enum UpdateError {\n    #[error(\"HTTP request failed: {0}\")]\n    RequestFailed(#[from] reqwest::Error),\n\n    #[error(\"Failed to parse update response: {0}\")]\n    ParseError(String),\n\n    #[error(\"All endpoints failed\")]\n    AllEndpointsFailed,\n\n    #[error(\"Invalid response from server: {0}\")]\n    InvalidResponse(String),\n\n    #[error(\"No endpoints configured\")]\n    NoEndpointsConfigured,\n}\n\n/// Update information returned by the update check endpoint\n/// Compatible with Tauri's updater format\n#[derive(Debug, Clone, Serialize, Deserialize)]","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/janhq/jan/blob/7205d770c1e097c3daf35a911176410e93bc5564/src-tauri/src/core/updater/custom_updater.rs#L13-L49","documentation":"UpdateError::RequestFailed wraps a reqwest::Error (via #[from]) whenever the custom updater's HTTP request to a version/check endpoint fails. The message renders as 'HTTP request failed: <reqwest detail>'.","triggerScenarios":"custom_updater issues a reqwest client request with REQUEST_TIMEOUT_SECS=30 and the connection cannot be established, DNS fails, TLS fails, or the request exceeds the timeout.","commonSituations":"Offline machine or corporate proxy blocking the update server, DNS misconfiguration, update endpoint temporarily down, or slow networks tripping the 30s timeout.","solutions":["Check network connectivity and whether the update endpoint is reachable","Verify the endpoint URL and any proxy configuration (HTTP_PROXY/HTTPS_PROXY)","Retry the update check; the updater iterates endpoints so a mirror may work","Increase REQUEST_TIMEOUT_SECS if 30s is too short for your environment"],"exampleFix":"// before\nconst REQUEST_TIMEOUT_SECS: u64 = 30;\n// after\nconst REQUEST_TIMEOUT_SECS: u64 = 60; // tolerate slow networks","handlingStrategy":"retry","validationCode":"const reachable = await fetch(endpoint, { method: 'HEAD', signal: AbortSignal.timeout(5000) }).then(r => r.ok).catch(() => false);\nif (!reachable) throw new Error('update endpoint unreachable, check network');","typeGuard":null,"tryCatchPattern":"match updater.check() {\n    Err(UpdateError::RequestFailed(e)) if e.is_timeout() || e.is_connect() => {\n        // exponential backoff retry, max 3 attempts\n    }\n    other => other?,\n}","preventionTips":["Check connectivity/proxy settings before update checks","Set sane reqwest timeouts and retry with backoff","Keep multiple endpoints as fallbacks","Verify DNS resolution for the update host in your deployment environment"],"tags":["network","http","updater","rust"],"backgroundTag":"http-request-failed","analyzedSha":"7205d770c1e097c3daf35a911176410e93bc5564","analyzedAt":"2026-09-17T14:27:30.100Z","contentChangedAt":"2026-09-17T14:27:30.100Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}