{"record":{"id":"1cc283977ee71509","repo":"tonhowtf/omniget","slug":"nao-esta-gravando-screen-record","errorCode":null,"errorMessage":"nao esta gravando","messagePattern":"nao esta gravando","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/screen_record.rs","lineNumber":421,"sourceCode":"async fn stop_child(mut child: tokio::process::Child) {\n    if let Some(mut stdin) = child.stdin.take() {\n        use tokio::io::AsyncWriteExt;\n        let _ = stdin.write_all(b\"q\\n\").await;\n        let _ = stdin.flush().await;\n    }\n    if tokio::time::timeout(std::time::Duration::from_secs(10), child.wait())\n        .await\n        .is_err()\n    {\n        let _ = child.kill().await;\n    }\n}\n\n/// Para a gravação. Normal: devolve o arquivo. Replay: descarta o anel.\npub async fn stop() -> anyhow::Result<RecordState> {\n    let sess = SESSION.lock().unwrap_or_else(|e| e.into_inner()).take();\n    let Some(sess) = sess else {\n        return Err(anyhow!(\"nao esta gravando\"));\n    };\n    stop_child(sess.child).await;\n    if let Some(out) = &sess.output {\n        *LAST_SAVED.lock().unwrap_or_else(|e| e.into_inner()) =\n            Some(out.to_string_lossy().to_string());\n    }\n    if let Some(r) = &sess.ring_dir {\n        let _ = std::fs::remove_dir_all(r);\n    }\n    Ok(state())\n}\n\n/// Replay: junta os últimos segmentos num arquivo na pasta de saída, sem\n/// interromper a gravação do anel.\npub async fn save_replay() -> anyhow::Result<String> {\n    let (ring, opts) = {\n        let s = SESSION.lock().unwrap_or_else(|e| e.into_inner());\n        let Some(sess) = s.as_ref() else {","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/screen_record.rs#L403-L439","documentation":"State guard in screen_record stop: the SESSION mutex was empty when stop() was called — no active recording exists (never started, already stopped, or the child died) — so there is no ffmpeg session to terminate and no file to return.","triggerScenarios":"Calling stop() when start() was never called, after stop() already ran (session is take()-n, so a second stop always fails), or after a previous start failed before registering the session.","commonSituations":"UI firing stop on shutdown regardless of recording state; double-clicking the stop button; scripts that unconditionally call stop in cleanup after a start that errored.","solutions":["Check state() (or the recording flag) before calling stop()","Treat this error as a no-op in cleanup paths: ignore 'nao esta gravando' errors","Ensure start/stop are paired one-to-one; do not call stop twice"],"exampleFix":"// before\nstop().await?; // fails if not recording\n// after\nmatch stop().await {\n    Ok(s) => println!(\"saved: {:?}\", s),\n    Err(e) if e.to_string().contains(\"nao esta gravando\") => {}, // nothing to do\n    Err(e) => return Err(e),\n}","handlingStrategy":"validation","validationCode":"if !screen_record::state().recording {\n    eprintln!(\"nothing to stop; skipping stop()\");\n}","typeGuard":null,"tryCatchPattern":"match screen_record::stop().await {\n    Ok(s) => println!(\"saved: {:?}\", s),\n    Err(e) if e.to_string().contains(\"nao esta gravando\") => { /* benign no-op */ }\n    Err(e) => return Err(e),\n}","preventionTips":["Track recording state in your app and only call stop() while recording","Treat 'not recording' as benign in cleanup/shutdown paths","Ensure start/stop calls are paired and idempotent at the call site"],"tags":["screen-recording","state","invalid-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}