Skip to content

Commit d4aa709

Browse files
committed
macos fail points
1 parent eb9d3bb commit d4aa709

File tree

10 files changed

+180
-123
lines changed

10 files changed

+180
-123
lines changed

apps/desktop/src-tauri/src/recording.rs

Lines changed: 101 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,6 @@ pub async fn start_recording(
305305
state.set_pending_recording();
306306
}
307307

308-
if let Some(window) = CapWindowId::Main.get(&app) {
309-
let _ = general_settings
310-
.map(|v| v.main_window_recording_start_behaviour)
311-
.unwrap_or_default()
312-
.perform(&window);
313-
}
314-
315308
let countdown = general_settings.and_then(|v| v.recording_countdown);
316309
let _ = ShowCapWindow::InProgressRecording { countdown }
317310
.show(&app)
@@ -343,86 +336,121 @@ pub async fn start_recording(
343336

344337
println!("spawning actor");
345338

346-
// done in spawn to catch panics just in case
347-
let actor_done_rx = spawn_actor({
348-
let state_mtx = Arc::clone(&state_mtx);
349-
let general_settings = general_settings.cloned();
350-
let capture_target = inputs.capture_target.clone();
351-
async move {
352-
fail!("recording::spawn_actor");
353-
let mut state = state_mtx.write().await;
354-
355-
let base_inputs = cap_recording::RecordingBaseInputs {
356-
capture_target,
357-
capture_system_audio: inputs.capture_system_audio,
358-
mic_feed: &state.mic_feed,
359-
};
360-
361-
let (actor, actor_done_rx) = match inputs.mode {
362-
RecordingMode::Studio => {
363-
let (handle, actor_done_rx) = cap_recording::spawn_studio_recording_actor(
364-
id.clone(),
365-
recording_dir.clone(),
366-
base_inputs,
367-
state.camera_feed.clone(),
368-
general_settings
369-
.map(|s| s.custom_cursor_capture)
370-
.unwrap_or_default(),
371-
)
372-
.await
373-
.map_err(|e| {
374-
error!("Failed to spawn studio recording actor: {e}");
375-
e.to_string()
376-
})?;
377-
378-
(
379-
InProgressRecording::Studio {
380-
handle,
381-
target_name,
382-
inputs,
383-
recording_dir: recording_dir.clone(),
384-
},
385-
actor_done_rx,
386-
)
387-
}
388-
RecordingMode::Instant => {
389-
let Some(video_upload_info) = video_upload_info.clone() else {
390-
return Err("Video upload info not found".to_string());
391-
};
339+
if let Some(window) = CapWindowId::Main.get(&app) {
340+
let _ = general_settings
341+
.map(|v| v.main_window_recording_start_behaviour)
342+
.unwrap_or_default()
343+
.perform(&window);
344+
}
392345

393-
let (handle, actor_done_rx) =
394-
cap_recording::instant_recording::spawn_instant_recording_actor(
346+
// done in spawn to catch panics just in case
347+
let spawn_actor_res = async {
348+
spawn_actor({
349+
let state_mtx = Arc::clone(&state_mtx);
350+
let general_settings = general_settings.cloned();
351+
let capture_target = inputs.capture_target.clone();
352+
async move {
353+
fail!("recording::spawn_actor");
354+
let mut state = state_mtx.write().await;
355+
356+
let base_inputs = cap_recording::RecordingBaseInputs {
357+
capture_target,
358+
capture_system_audio: inputs.capture_system_audio,
359+
mic_feed: &state.mic_feed,
360+
};
361+
362+
let (actor, actor_done_rx) = match inputs.mode {
363+
RecordingMode::Studio => {
364+
let (handle, actor_done_rx) = cap_recording::spawn_studio_recording_actor(
395365
id.clone(),
396366
recording_dir.clone(),
397367
base_inputs,
368+
state.camera_feed.clone(),
369+
general_settings
370+
.map(|s| s.custom_cursor_capture)
371+
.unwrap_or_default(),
398372
)
399373
.await
400374
.map_err(|e| {
401375
error!("Failed to spawn studio recording actor: {e}");
402376
e.to_string()
403377
})?;
404378

405-
(
406-
InProgressRecording::Instant {
407-
handle,
408-
progressive_upload,
409-
video_upload_info,
410-
target_name,
411-
inputs,
412-
recording_dir: recording_dir.clone(),
413-
},
414-
actor_done_rx,
415-
)
416-
}
417-
};
379+
(
380+
InProgressRecording::Studio {
381+
handle,
382+
target_name,
383+
inputs,
384+
recording_dir: recording_dir.clone(),
385+
},
386+
actor_done_rx,
387+
)
388+
}
389+
RecordingMode::Instant => {
390+
let Some(video_upload_info) = video_upload_info.clone() else {
391+
return Err("Video upload info not found".to_string());
392+
};
418393

419-
state.set_current_recording(actor);
394+
let (handle, actor_done_rx) =
395+
cap_recording::instant_recording::spawn_instant_recording_actor(
396+
id.clone(),
397+
recording_dir.clone(),
398+
base_inputs,
399+
)
400+
.await
401+
.map_err(|e| {
402+
error!("Failed to spawn studio recording actor: {e}");
403+
e.to_string()
404+
})?;
405+
406+
(
407+
InProgressRecording::Instant {
408+
handle,
409+
progressive_upload,
410+
video_upload_info,
411+
target_name,
412+
inputs,
413+
recording_dir: recording_dir.clone(),
414+
},
415+
actor_done_rx,
416+
)
417+
}
418+
};
420419

421-
Ok::<_, String>(actor_done_rx)
420+
state.set_current_recording(actor);
421+
422+
Ok::<_, String>(actor_done_rx)
423+
}
424+
})
425+
.await
426+
.map_err(|e| format!("Failed to spawn recording actor: {e}"))?
427+
}
428+
.await;
429+
430+
let actor_done_rx = match spawn_actor_res {
431+
Ok(rx) => rx,
432+
Err(e) => {
433+
let _ = RecordingEvent::Failed { error: e.clone() }.emit(&app);
434+
435+
let mut dialog = MessageDialogBuilder::new(
436+
app.dialog().clone(),
437+
"An error occurred".to_string(),
438+
e.clone(),
439+
)
440+
.kind(tauri_plugin_dialog::MessageDialogKind::Error);
441+
442+
if let Some(window) = CapWindowId::InProgressRecording.get(&app) {
443+
dialog = dialog.parent(&window);
444+
}
445+
446+
dialog.blocking_show();
447+
448+
let mut state = state_mtx.write().await;
449+
let _ = handle_recording_end(app, None, &mut state).await;
450+
451+
return Err(e);
422452
}
423-
})
424-
.await
425-
.map_err(|e| format!("Failed to spawn recording actor: {e}"))??;
453+
};
426454

427455
let _ = RecordingEvent::Started.emit(&app);
428456

apps/desktop/src/utils/tauri.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,8 @@ export type HotkeysConfiguration = { show: boolean };
588588
export type HotkeysStore = { hotkeys: { [key in HotkeyAction]: Hotkey } };
589589
export type InstantRecordingMeta = { fps: number; sample_rate: number | null };
590590
export type JsonValue<T> = [T];
591+
export type LayoutMode = "default" | "cameraOnly" | "hideCamera";
592+
export type LayoutSegment = { start: number; end: number; mode?: LayoutMode };
591593
export type LogicalBounds = { position: LogicalPosition; size: LogicalSize };
592594
export type LogicalPosition = { x: number; y: number };
593595
export type LogicalSize = { width: number; height: number };
@@ -741,12 +743,6 @@ export type TargetUnderCursor = {
741743
window: WindowUnderCursor | null;
742744
screen: ScreenUnderCursor | null;
743745
};
744-
export type LayoutSegment = {
745-
start: number;
746-
end: number;
747-
mode?: "default" | "cameraOnly" | "hideCamera";
748-
};
749-
750746
export type TimelineConfiguration = {
751747
segments: TimelineSegment[];
752748
zoomSegments: ZoomSegment[];

crates/fail/src/lib.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ macro_rules! fail {
2222
($name:literal) => {
2323
#[cfg(debug_assertions)]
2424
{
25+
const NAME: &'static str = concat!(env!("CARGO_PKG_NAME"), "::", $name);
26+
2527
$crate::private::inventory::submit! {
26-
$crate::Fail { name: $name }
28+
$crate::Fail { name: NAME }
2729
}
2830

29-
let name: &str = $name;
30-
let should_fail = $crate::private::should_fail(name);
31+
let should_fail = $crate::private::should_fail(NAME);
3132

3233
if should_fail {
33-
panic!("Purposely panicked at '{name}'")
34+
panic!("Purposely panicked at '{NAME}'")
3435
}
3536
}
3637
};
@@ -41,15 +42,16 @@ macro_rules! fail_err {
4142
($name:literal, $value:expr) => {
4243
#[cfg(debug_assertions)]
4344
{
45+
const NAME: &'static str = concat!(env!("CARGO_PKG_NAME"), "::", $name);
46+
4447
$crate::private::inventory::submit! {
45-
$crate::Fail { name: $name }
48+
$crate::Fail { name: NAME }
4649
}
4750

48-
let name: &str = $name;
49-
let should_fail = $crate::private::should_fail(name);
51+
let should_fail = $crate::private::should_fail(NAME);
5052

5153
if should_fail {
52-
eprintln!("Purposely Err'd at '{name}'");
54+
eprintln!("Purposely Err'd at '{NAME}'");
5355
Err($value)?;
5456
}
5557
}

crates/recording/examples/recording-cli.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
use std::time::Duration;
22

33
use cap_displays::Display;
4-
use cap_recording::{
5-
RecordingBaseInputs, screen_capture::ScreenCaptureTarget, sources::list_windows,
6-
};
4+
use cap_recording::{RecordingBaseInputs, screen_capture::ScreenCaptureTarget};
75

86
#[tokio::main]
97
pub async fn main() {

crates/recording/src/pipeline/builder.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,16 @@ impl PipelineBuilder {
4040
let name = name.into();
4141
let control_signal = self.control.add_listener(name.clone());
4242

43-
self.spawn_task(name, move |ready_signal| {
44-
task.run(ready_signal, control_signal)
43+
self.spawn_task(name.clone(), move |ready_signal| {
44+
let res = task.run(ready_signal.clone(), control_signal);
45+
46+
if let Err(e) = &res
47+
&& !ready_signal.is_disconnected()
48+
{
49+
let _ = ready_signal.send(Err(MediaError::Any(format!("Task/{name}/{e}").into())));
50+
}
51+
52+
res
4553
});
4654
}
4755

@@ -123,7 +131,7 @@ impl PipelineBuilder {
123131
tokio::time::timeout(Duration::from_secs(5), task.ready_signal.recv_async())
124132
.await
125133
.map_err(|_| MediaError::TaskLaunch(format!("task timed out: '{name}'")))?
126-
.map_err(|e| MediaError::TaskLaunch(format!("{name} build / {e}")))??;
134+
.map_err(|e| MediaError::TaskLaunch(format!("'{name}' build / {e}")))??;
127135

128136
task_handles.insert(name.clone(), task.join_handle);
129137
stop_rx.push(task.done_rx);
@@ -139,8 +147,8 @@ impl PipelineBuilder {
139147
let task_name = &task_names[index];
140148

141149
let result = match result {
142-
Ok(Err(error)) => Err(format!("Task '{task_name}' failed: {error}")),
143-
Err(_) => Err(format!("Task '{task_name}' failed for unknown reason")),
150+
Ok(Err(error)) => Err(format!("Task/{task_name}/{error}")),
151+
Err(_) => Err(format!("Task/{task_name}/Unknown")),
144152
_ => Ok(()),
145153
};
146154

crates/recording/src/pipeline/control.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub enum Control {
88
Shutdown,
99
}
1010

11+
#[derive(Clone)]
1112
pub struct PipelineControlSignal {
1213
last_value: Option<Control>,
1314
receiver: Receiver<Control>,

0 commit comments

Comments
 (0)