fix(A.2 #19): only report audio_path when the WAV writer finalises cleanly
Review feedback: reported_audio_path was cached at writer-open time and survived a mid-session writer drop. If an append error cleared wav_writer (or hound's Drop ran instead of finalize), the Summary still reported the path — risking StopLiveTranscriptionResponse pointing at a file whose header did not reflect its data chunk. Moves the decision to end-of-session. wav_writer.take() is inspected: - writer present + finalize Ok → report the path, - writer present + finalize Err → None, emit a Warning, - writer absent (mid-session drop, or never opened) → None. StopLiveTranscriptionResponse.audio_path now means "the recording is known-good" rather than "a recording was attempted". Users can still recover partial files via filesystem if needed; the warning toasts already emitted by append_resampled_audio on write failure surface that path implicitly.
This commit is contained in:
@@ -402,15 +402,12 @@ fn run_live_session(
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
// Resolve the reported audio_path only if the writer actually
|
||||
// opened; otherwise the returned Summary must not claim a path.
|
||||
let reported_audio_path: Option<String> = if wav_writer.is_some() {
|
||||
audio_path
|
||||
.as_ref()
|
||||
.map(|p| p.to_string_lossy().to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
// `reported_audio_path` is decided at end-of-session based on
|
||||
// whether the writer finalised successfully, not at open time.
|
||||
// This way a writer that dies mid-session (append error clearing
|
||||
// wav_writer, or finalise returning Err) does not leak a stale
|
||||
// path back to the frontend that might point to a file whose
|
||||
// header is out of sync with its data chunk.
|
||||
|
||||
let mut buffer_start_sample: u64 = 0;
|
||||
let mut dropped_audio_ms: u64 = 0;
|
||||
@@ -552,23 +549,32 @@ fn run_live_session(
|
||||
thread::sleep(Duration::from_millis(10));
|
||||
}
|
||||
|
||||
// Finalise the progressive WAV writer so the terminal header
|
||||
// reflects every written sample. A failure here leaves the last
|
||||
// flushed header state on disk — still a playable WAV — so we
|
||||
// report a warning but don't fail the whole session.
|
||||
if let Some(writer) = wav_writer.take() {
|
||||
if let Err(e) = writer.finalize() {
|
||||
let _ = status_channel.send(LiveStatusMessage::Warning {
|
||||
session_id,
|
||||
message: format!("WAV finalise failed: {e}; partial recording is still playable."),
|
||||
});
|
||||
}
|
||||
}
|
||||
// Finalise the progressive WAV writer and decide whether to
|
||||
// report a path to the frontend. Only a clean finalise produces a
|
||||
// reported path: a writer that died mid-session (wav_writer was
|
||||
// already None) or a finalise that itself errored both yield
|
||||
// `None`, so `StopLiveTranscriptionResponse.audio_path` reflects
|
||||
// "recording is known-good" rather than "recording was attempted".
|
||||
let audio_path = match wav_writer.take() {
|
||||
Some(writer) => match writer.finalize() {
|
||||
Ok(()) => audio_path.as_ref().map(|p| p.to_string_lossy().to_string()),
|
||||
Err(e) => {
|
||||
let _ = status_channel.send(LiveStatusMessage::Warning {
|
||||
session_id,
|
||||
message: format!(
|
||||
"WAV finalise failed: {e}. A partial recording may still be on disk from earlier flushes."
|
||||
),
|
||||
});
|
||||
None
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
Ok(LiveSessionSummary {
|
||||
session_id,
|
||||
dropped_audio_ms,
|
||||
audio_path: reported_audio_path,
|
||||
audio_path,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user