fix(android): 8s Rust timeout on audio_start; always emit connect: debug events
- engine.rs: wrap spawn_blocking(audio_start) in an 8s tokio timeout so the connect command fails fast with a clear error if the Oboe HAL never returns, instead of blocking the JS 45s timer - lib.rs: emit_call_debug now always forwards connect: and register_signal: steps to the JS overlay regardless of the debug-logs toggle — needed because app-data clears reset the toggle to false, making join failures invisible on first install - main.ts: JS timeout bumped to 45s (Rust 8s fires first); timeout message now includes last native connect: step so the toast is actionable without opening the debug log Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -683,19 +683,32 @@ impl CallEngine {
|
||||
"connect:audio_start_start",
|
||||
serde_json::json!({ "t_ms": t_pre_audio }),
|
||||
);
|
||||
let audio_start_result = tokio::task::spawn_blocking(crate::wzp_native::audio_start)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
crate::emit_call_debug(
|
||||
&app,
|
||||
"connect:audio_start_panic",
|
||||
serde_json::json!({
|
||||
"t_ms": call_t0.elapsed().as_millis(),
|
||||
"error": e.to_string(),
|
||||
}),
|
||||
);
|
||||
anyhow::anyhow!("audio_start task panic: {e}")
|
||||
})?;
|
||||
let audio_start_task = tokio::task::spawn_blocking(crate::wzp_native::audio_start);
|
||||
let audio_start_result =
|
||||
match tokio::time::timeout(std::time::Duration::from_secs(8), audio_start_task).await {
|
||||
Ok(join_result) => join_result.map_err(|e| {
|
||||
crate::emit_call_debug(
|
||||
&app,
|
||||
"connect:audio_start_panic",
|
||||
serde_json::json!({
|
||||
"t_ms": call_t0.elapsed().as_millis(),
|
||||
"error": e.to_string(),
|
||||
}),
|
||||
);
|
||||
anyhow::anyhow!("audio_start task panic: {e}")
|
||||
})?,
|
||||
Err(_) => {
|
||||
crate::emit_call_debug(
|
||||
&app,
|
||||
"connect:audio_start_timeout",
|
||||
serde_json::json!({
|
||||
"t_ms": call_t0.elapsed().as_millis(),
|
||||
"timeout_ms": 8000,
|
||||
}),
|
||||
);
|
||||
return Err(anyhow::anyhow!("wzp_native_audio_start timed out after 8s"));
|
||||
}
|
||||
};
|
||||
if let Err(code) = audio_start_result {
|
||||
crate::emit_call_debug(
|
||||
&app,
|
||||
|
||||
@@ -59,13 +59,15 @@ fn set_call_debug_logs_internal(on: bool) {
|
||||
CALL_DEBUG_LOGS.store(on, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Emit a `call-debug-log` event to the JS side IF the flag is on.
|
||||
/// Emit a `call-debug-log` event to the JS side.
|
||||
/// Also mirrors to `tracing::info!` so logcat keeps its copy
|
||||
/// regardless of the flag — the toggle only controls the GUI
|
||||
/// overlay, not the underlying Android log stream.
|
||||
/// regardless of the flag. Connect/register steps are always emitted
|
||||
/// because they are needed to diagnose failed joins after app data is
|
||||
/// cleared and the GUI debug toggle is back to its default false value.
|
||||
pub(crate) fn emit_call_debug(app: &tauri::AppHandle, step: &str, details: serde_json::Value) {
|
||||
tracing::info!(step, ?details, "call-debug");
|
||||
if !call_debug_logs_enabled() {
|
||||
let force_emit = step.starts_with("connect:") || step.starts_with("register_signal:");
|
||||
if !force_emit && !call_debug_logs_enabled() {
|
||||
return;
|
||||
}
|
||||
let payload = serde_json::json!({
|
||||
|
||||
Reference in New Issue
Block a user