cjpais/Handy · error
Failed to create AudioRecorder: {}
Error message
Failed to create AudioRecorder: {} What it means
Wraps AudioRecorder::new() in create_audio_recorder (audio.rs:284). Note: in the current code the constructor is effectively infallible — recorder.rs:92-103 only builds the struct and returns Ok(()) — so this error is a defensive guard that should not fire today. If it ever fires, the constructor has gained fallible work (host enumeration, worker thread spawn) and {e} holds that cause.
Source
Thrown at src-tauri/src/managers/audio.rs:284
stream_router: Arc<StreamRouter>,
) -> Result<AudioRecorder, anyhow::Error> {
// A single Silero engine covers both the offline and streaming policies (never
// active at once within a recording), so the recorder reconfigures its
// hangover tail per session rather than keeping two ONNX sessions resident.
let silero = SileroVad::new(vad_path, VAD_THRESHOLD)
.map_err(|e| anyhow::anyhow!("Failed to create SileroVad: {}", e))?;
let smoothed_vad = SmoothedVad::new(
Box::new(silero),
VAD_PREFILL_FRAMES,
VAD_OFFLINE_HANGOVER_FRAMES,
VAD_ONSET_FRAMES,
);
// Recorder with VAD, a spectrum-level callback that forwards level updates to
// the frontend, and an audio-frame callback that feeds live streaming via a
// shared `StreamRouter` (captured directly, not via Tauri state — see its docs).
let recorder = AudioRecorder::new()
.map_err(|e| anyhow::anyhow!("Failed to create AudioRecorder: {}", e))?
.with_vad(
Box::new(smoothed_vad),
VAD_OFFLINE_HANGOVER_FRAMES,
VAD_STREAMING_HANGOVER_FRAMES,
)
.with_selected_channel(selected_channel)
.with_level_callback({
let app_handle = app_handle.clone();
move |levels| {
utils::emit_levels(&app_handle, &levels);
}
})
.with_audio_callback({
let router = stream_router;
move |frame| {
router.feed(frame);
}
});View on GitHub (pinned to 98a4d80cce)
Solutions
- Inspect the {e} payload — it identifies whatever fallible step the constructor now performs
- If seen with the current code, treat it as a bug: file it against the constructor contract rather than the environment
- Check system resources (threads/memory) if the constructor spawns a worker
Defensive patterns
Strategy: try-catch
Try / catch
let recorder = AudioRecorder::new()
.map_err(|e| anyhow::anyhow!("AudioRecorder init failed: {e}"))?; Prevention
- Keep AudioRecorder::new infallible (pure construction) so this guard stays dead code
- If the constructor gains fallible steps, move them to explicit fallible methods callers can handle separately
When it happens
Trigger: Calling create_audio_recorder after AudioRecorder::new was changed to do fallible initialization (e.g. enumerating the cpal host or spawning the audio worker thread fails). With the present implementation there is no runtime condition that produces it.
Common situations: Future refactors that move cpal host/device queries into new(); a failed thread spawn under thread/memory exhaustion; effectively unreachable in the shipped code.
Related errors
- Failed to open recorder: {}
- threshold must be between 0.0 and 1.0
- Failed to create VAD: {e}
- Failed to create SileroVad: {}
- Failed to resolve VAD path: {}
AI-assisted analysis of cjpais/Handy@98a4d80cce (2026-08-16).
Data as JSON: /api/errors/332dc37fcbbede3d.
Report an issue: GitHub.