Skip to content

Conversation

oscartbeaumont
Copy link
Member

@oscartbeaumont oscartbeaumont commented Aug 18, 2025

  • Add a retry loop and timeout as Tauri is erroring out sometimes. This could be due to the window not being ready or some other reason.
  • Enable the camera preview in development and on macOS to ensure the Cap team are properly testing it

Summary by CodeRabbit

  • Bug Fixes

    • Native camera preview initialization is now more reliable with automatic retries and a short timeout, reducing intermittent startup failures and improving stability.
  • Chores

    • In macOS debug builds, the native camera preview is enabled by default to aid internal testing. Behavior remains unchanged for release builds and other platforms.

Copy link
Contributor

coderabbitai bot commented Aug 18, 2025

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch native-camera-preview-timeout

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
apps/desktop/src-tauri/src/lib.rs (1)

266-279: New init attempts aren’t cancelable externally due to not updating the shutdown handle

If a previous initialization was in progress, you send a cancel to the old handle but don’t store the new shutdown_tx. That leaves the new init attempt without an externally reachable cancel handle (app.camera_feed_initialization still points at the old sender).

Make sure to replace the stored sender unconditionally when starting a new init:

// Always replace the previous handle with the new one so external code can cancel this attempt.
if let Some(prev) = app.camera_feed_initialization.replace(shutdown_tx.clone()) {
    // Ask currently running setup to abort
    prev.send(()).await.ok();

    // We can assume a window was already initialized.
    if let Some(win) = CapWindowId::Camera.get(&app_handle) {
        let _ = win.close();
    }
}

This preserves the ability to cancel the most recent initialization attempt at any time.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 801757a and 77dd0fe.

📒 Files selected for processing (2)
  • apps/desktop/src-tauri/src/general_settings.rs (1 hunks)
  • apps/desktop/src-tauri/src/lib.rs (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (3)
apps/desktop/src-tauri/src/general_settings.rs (1)

102-104: Enable-by-default on macOS debug builds looks good

The gated default via cfg!(all(debug_assertions, target_os = "macos")) aligns with the PR goal to exercise the feature in dev on macOS.

apps/desktop/src-tauri/src/lib.rs (2)

59-59: Necessary import added

Importing Duration is required for the timeout/sleep logic.


81-81: Timeout import added appropriately

tokio::time::timeout is correctly brought into scope.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
apps/desktop/src-tauri/src/lib.rs (1)

266-279: Cancellation handle is not updated; new attempts can’t be cancelled

When a previous initialization is in-flight, you send a cancel signal but don’t replace app.camera_feed_initialization with the new shutdown_tx. Subsequent cancellations target the stale sender and won’t abort the current attempt. Also, avoid unwrap() on close().

Apply:

-            let (shutdown_tx, mut shutdown_rx) = mpsc::channel(1);
-            if let Some(cancel) = app.camera_feed_initialization.as_ref() {
+            let (shutdown_tx, mut shutdown_rx) = mpsc::channel(1);
+            if let Some(cancel) = app.camera_feed_initialization.replace(shutdown_tx) {
                 // Ask currently running setup to abort
                 cancel.send(()).await.ok();
 
                 // We can assume a window was already initialized.
                 // Stop it so we can recreate it with the correct `camera_tx`
                 if let Some(win) = CapWindowId::Camera.get(&app_handle) {
-                    win.close().unwrap(); // TODO: Error handling
+                    let _ = win.close();
                 };
-            } else {
-                app.camera_feed_initialization = Some(shutdown_tx);
-            }
+            }
♻️ Duplicate comments (1)
apps/desktop/src-tauri/src/lib.rs (1)

292-309: Make retry loop cancellable and report last error as a string

Two issues:

  • Not cancellable: The retry loop ignores shutdown_rx, so a new call cannot abort preview init immediately.
  • Error accumulation: &mut None + storing raw error is awkward and may capture a non-Send error type; prefer Option<String>.

You already fixed the orphan-window by closing on timeout—nice.

Proposed refactor (cancellable, cleaner error message):

-                let prev_err = &mut None;
-                if timeout(Duration::from_secs(3), async {
-                    while let Err(err) = camera_preview
-                        .init_preview_window(window.clone(), camera_rx.clone())
-                        .await
-                    {
-                        error!("Error initializing camera feed: {err}");
-                        *prev_err = Some(err);
-                        tokio::time::sleep(Duration::from_millis(200)).await;
-                    }
-                })
-                .await
-                .is_err()
-                {
-                    let _ = window.close();
-                    return Err(format!("Timeout initializing camera preview: {prev_err:?}"));
-                };
+                let mut last_err: Option<String> = None;
+                let last_err_ref = &mut last_err;
+                let init_result = timeout(Duration::from_secs(3), async {
+                    loop {
+                        tokio::select! {
+                            // Abort immediately if a new init request cancels this attempt
+                            _ = shutdown_rx.recv() => return Err::<(), ()>(()),
+                            res = camera_preview.init_preview_window(window.clone(), camera_rx.clone()) => {
+                                match res {
+                                    Ok(()) => return Ok(()),
+                                    Err(err) => {
+                                        error!("Error initializing camera feed: {err}");
+                                        *last_err_ref = Some(err.to_string());
+                                        tokio::time::sleep(Duration::from_millis(200)).await;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                })
+                .await;
+                match init_result {
+                    Ok(Ok(())) => {}
+                    Ok(Err(())) => {
+                        let _ = window.close();
+                        return Ok(false);
+                    }
+                    Err(_) => {
+                        let _ = window.close();
+                        return Err(format!(
+                            "Timeout initializing camera preview: {}",
+                            last_err.as_deref().unwrap_or("unknown error")
+                        ));
+                    }
+                }
🧹 Nitpick comments (1)
apps/desktop/src-tauri/src/lib.rs (1)

280-281: Avoid unwrap on window creation

ShowCapWindow::Camera.show(...).await.unwrap() will crash the app if the window fails to build (the very case you’re mitigating). Propagate a typed error instead.

Apply:

-            let window = ShowCapWindow::Camera.show(&app_handle).await.unwrap();
+            let window = ShowCapWindow::Camera
+                .show(&app_handle)
+                .await
+                .map_err(|e| format!("Failed to show camera window: {e}"))?;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 77dd0fe and 3808ae2.

📒 Files selected for processing (1)
  • apps/desktop/src-tauri/src/lib.rs (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (2)
apps/desktop/src-tauri/src/lib.rs (2)

59-59: LGTM: Needed import for timeout duration

Importing Duration is correct for the retry/timeout logic.


81-81: LGTM: tokio timeout import added

Importing tokio::time::timeout is appropriate for the new retry logic.

@Brendonovich Brendonovich merged commit 26eba96 into main Aug 18, 2025
15 checks passed
@oscartbeaumont oscartbeaumont deleted the native-camera-preview-timeout branch August 18, 2025 06:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants