{"record":{"id":"addbb50197697cff","repo":"tonhowtf/omniget","slug":"e-code-to-string","errorCode":null,"errorMessage":"e.code().to_string()","messagePattern":"e\\.code\\(\\)\\.to_string\\(\\)","errorType":"error_code","errorClass":"StreamError","httpStatus":null,"severity":"warning","filePath":"src-tauri/src/commands/omnidisc/stream.rs","lineNumber":31,"sourceCode":"use tokio::sync::Mutex;\n\npub struct StreamManager {\n    active: Mutex<Option<ActiveStream>>,\n    viewers: Mutex<HashMap<String, Viewer>>,\n    preview_gen: AtomicU64,\n}\n\nimpl Default for StreamManager {\n    fn default() -> Self {\n        Self {\n            active: Mutex::new(None),\n            viewers: Mutex::new(HashMap::new()),\n            preview_gen: AtomicU64::new(0),\n        }\n    }\n}\n\nfn err(e: StreamError) -> String {\n    e.code().to_string()\n}\n\nfn backend(state: &crate::AppState) -> Result<Arc<LiveKitBackend>, String> {\n    state\n        .omnidisc_voice\n        .livekit_backend()\n        .ok_or_else(|| \"ERR_VOICE_UNAVAILABLE\".to_string())\n}\n\nfn emit_voice(\n    app: &tauri::AppHandle,\n    url: Option<String>,\n    event: &str,\n    mut payload: serde_json::Value,\n) {\n    if let serde_json::Value::Object(map) = &mut payload {\n        map.insert(\"type\".into(), json!(event));","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/commands/omnidisc/stream.rs#L13-L49","documentation":"stream.rs defines a helper err(e: StreamError) -> String that maps a StreamError to its machine-readable error code via e.code().to_string() — the message shown here is the dynamic code value produced by that mapping. These strings are the error contract returned by the omnidisc stream Tauri commands (e.g. \"BACKEND_UNAVAILABLE\"-style codes).","triggerScenarios":"Any omnidisc stream command that returns Result<_, String> converts its StreamError through err(), surfacing e.code().to_string() to the frontend; the frontend then receives the code string as the rejection reason.","commonSituations":"Frontend calls a stream command while the LiveKit backend is not configured/connected; preview or viewer operations run against an uninitialized state; handling the rejection expecting a human message but receiving a bare code.","solutions":["In the frontend, match on the returned code string instead of displaying it raw; map codes to user-facing messages.","Check backend() configuration (omnidisc_voice state) before invoking stream commands to avoid backend-unavailable codes.","Include the error detail alongside the code (e.g. format!(\"{}: {}\", e.code(), e)) for easier debugging.","Define the codes as an enum shared between Rust and TS to avoid string mismatches."],"exampleFix":"// before\nfn err(e: StreamError) -> String {\n    e.code().to_string()\n}\n\n// after\nfn err(e: StreamError) -> String {\n    format!(\"{}: {}\", e.code(), e) // keep code stable prefix, add human-readable detail\n}","handlingStrategy":"type-guard","validationCode":"const STREAM_CODES = new Set(['BACKEND_UNAVAILABLE', 'PREVIEW_FAILED', 'VIEWER_LIMIT']);\nfunction isStreamCode(v: unknown): v is string {\n  return typeof v === 'string' && STREAM_CODES.has(v);\n}","typeGuard":"function isStreamCode(v: unknown): v is StreamErrorCode {\n  return typeof v === 'string' && STREAM_CODES.includes(v as StreamErrorCode);\n}","tryCatchPattern":"try {\n  await invoke('omnidisc_stream_preview', args);\n} catch (e) {\n  if (isStreamCode(e)) showError(STREAM_CODE_MESSAGES[e]);\n  else showError(String(e));\n}","preventionTips":["Verify backend configuration before invoking stream commands","Share the error-code enum between Rust and the frontend","Display mapped messages, never raw codes, to users"],"tags":["error-handling","tauri","livekit","rust"],"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"}