{"record":{"id":"75276aa955470877","repo":"tonhowtf/omniget","slug":"omnidisc-stop-stream-failed","errorCode":null,"errorMessage":"[omnidisc] stop stream failed","messagePattern":"\\[omnidisc\\] stop stream failed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/lib/stores/omnidisc-stream-store.svelte.ts","lineNumber":263,"sourceCode":"  lastError = null;\n  try {\n    const policy = currentPolicy() ?? undefined;\n    publishing = await invoke<PublishStats>(\"omnidisc_stream_start\", { args: { ...args, policy } });\n    return true;\n  } catch (e) {\n    lastError = errorText(e);\n    return false;\n  } finally {\n    busy = false;\n  }\n}\n\nexport async function stopStream(): Promise<void> {\n  busy = true;\n  try {\n    await invoke(\"omnidisc_stream_stop\");\n  } catch (e) {\n    console.warn(\"[omnidisc] stop stream failed\", errorText(e));\n  } finally {\n    publishing = null;\n    busy = false;\n  }\n}\n\nexport async function watchStream(userId: string): Promise<boolean> {\n  busy = true;\n  lastError = null;\n  try {\n    await invoke(\"omnidisc_stream_watch\", { userId });\n    if (!watchingIds.includes(userId)) watchingIds = [...watchingIds, userId];\n    return true;\n  } catch (e) {\n    lastError = errorText(e);\n    return false;\n  } finally {\n    busy = false;","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src/lib/stores/omnidisc-stream-store.svelte.ts#L245-L281","documentation":"stopStream invokes the backend command `omnidisc_stream_stop` to tear down an active stream. If the backend rejects (command missing, panic, or no active stream in its state), the rejection is caught and logged as this warning. The finally block still clears `publishing` and `busy`, so UI state is reset even on failure.","triggerScenarios":"Calling stopStream() when no stream is actually running in the backend, when the Rust `omnidisc_stream_stop` command panics (e.g. poisoned lock, missing publisher), or when the command is absent from the built backend.","commonSituations":"Double-clicking a stop button causing a second stop on an already-stopped stream; backend restarted while frontend still thinks a stream is live; version mismatch between frontend command names and Rust handlers.","solutions":["Make the backend `omnidisc_stream_stop` idempotent: return Ok even when no stream is active.","Guard the frontend call: only invoke stop when `publishing !== null` or a stream is known active.","Check the backend log for the panic/error detail returned in errorText(e).","Rebuild the backend to ensure the command exists and matches the invoked name."],"exampleFix":"// before\nawait invoke(\"omnidisc_stream_stop\");\n// after\nif (publishing !== null) {\n  await invoke(\"omnidisc_stream_stop\");\n}","handlingStrategy":"try-catch","validationCode":"if (publishing === null) return; // nothing to stop","typeGuard":null,"tryCatchPattern":"try {\n  await invoke(\"omnidisc_stream_stop\");\n} catch (e) {\n  console.warn(\"[omnidisc] stop stream failed\", errorText(e));\n} finally {\n  publishing = null; // always reset local state\n}","preventionTips":["Disable the stop button while busy to prevent duplicate invokes.","Make backend stop idempotent for already-stopped streams.","Re-sync UI state from omnidisc_stream_stats after a failed stop.","Log errorText(e) details to distinguish 'not active' from real backend faults."],"tags":["tauri","ipc","streaming","stop"],"backgroundTag":"api-request-failed","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"}