{"record":{"id":"f9e7ad17797ab204","repo":"tonhowtf/omniget","slug":"relay-error","errorCode":null,"errorMessage":"Relay error: {}","messagePattern":"Relay error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/platforms/p2p.rs","lineNumber":47,"sourceCode":"    .map_err(|_| anyhow!(\"Connection to relay timed out (10s)\"))?\n    .map_err(|e| anyhow!(\"Failed to connect to relay {}: {}\", addr, e))?;\n    Ok(stream)\n}\n\nasync fn read_line(\n    reader: &mut BufReader<tokio::io::ReadHalf<TcpStream>>,\n) -> anyhow::Result<String> {\n    let mut line = String::new();\n    let n = reader.read_line(&mut line).await?;\n    if n == 0 {\n        anyhow::bail!(\"Relay closed connection unexpectedly\");\n    }\n    Ok(line.trim_end().to_string())\n}\n\nfn check_relay_error(line: &str) -> anyhow::Result<()> {\n    if let Some(err) = line.strip_prefix(\"ERROR \") {\n        anyhow::bail!(\"Relay error: {}\", err);\n    }\n    Ok(())\n}\n\npub struct P2pDownloader;\n\nimpl P2pDownloader {\n    pub fn new() -> Self {\n        Self\n    }\n}\n\n#[async_trait]\nimpl PlatformDownloader for P2pDownloader {\n    fn name(&self) -> &str {\n        \"p2p\"\n    }\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/p2p.rs#L29-L65","documentation":"p2p.rs raises this in check_relay_error() when a line received from the relay starts with 'ERROR '. The relay-reported error text is extracted and wrapped as 'Relay error: {}'. This is the relay's way of signalling protocol/application failures (e.g. unknown code, no peer paired) back to the client.","triggerScenarios":"Any relay response line with the 'ERROR ' prefix passed to check_relay_error() — called after read_line in download and run_sender. Examples: 'ERROR unknown code', 'ERROR peer not connected', relay-side rate limits or protocol violations.","commonSituations":"Typo'd or expired share code rejected by relay; connecting as receiver before the sender has registered; relay configured with different protocol version; relay under load rejecting new sessions.","solutions":["Read the relay's message after the 'ERROR ' prefix — it states the exact relay-side cause.","Verify the share code is correct and still active on the relay (see also 'Invalid share code').","Ensure the sender is connected and registered with the relay before the receiver joins.","Match relay and client protocol versions; update the client if the relay was upgraded.","If the relay is overloaded or misconfigured, restart it or check its configuration/logs."],"exampleFix":"// before\nlet line = read_line(&mut reader).await?;\ncheck_relay_error(&line)?;\n// after\nlet line = read_line(&mut reader).await?;\nif let Err(e) = check_relay_error(&line) {\n    let relay_msg = e.to_string().trim_start_matches(\"Relay error: \").to_string();\n    if relay_msg.contains(\"unknown code\") {\n        return Err(anyhow!(\"Share code not found on relay: {}\", relay_msg));\n    }\n    return Err(e);\n}","handlingStrategy":"try-catch","validationCode":"// pre-check the response shape yourself\nif let Some(err) = line.strip_prefix(\"ERROR \") {\n    eprintln!(\"relay rejected: {err}\");\n}","typeGuard":"// Rust\nfn is_relay_error(line: &str) -> Option<&str> {\n    line.strip_prefix(\"ERROR \")\n}","tryCatchPattern":"let line = read_line(&mut reader).await?;\ncheck_relay_error(&line).map_err(|e| {\n    anyhow!(\"relay refused operation: {}. verify the share code and sender status\", e)\n})?;","preventionTips":["Validate the share code before contacting the relay","Ensure the sender has registered with the relay before the receiver connects","Keep client and relay protocol versions in sync","Log raw relay lines to diagnose protocol mismatches"],"tags":["network","p2p","relay","protocol"],"backgroundTag":"api-error-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"}