flxzt/rnote · warning · anyhow::Error

Channel closed before receiving a response from dialog.

Error message

Channel closed before receiving a response from dialog.

What it means

Thrown when the password dialog's response channel closes before a response arrives, i.e. `rx.borrow_mut().recv()` in `dialog_import_pdf_w_prefs` returned None because the dialog's sender was dropped without the user answering. The function cannot proceed with import, so it errors instead of silently succeeding.

Solutions

  1. Treat dialog dismissal (cancel/close) as a user-abort and return Ok(false) rather than an error, if abort is acceptable.
  2. Ensure the dialog always emits a response signal on cancel and the channel sender outlives the dialog lifetime.
  3. Retry the import flow by re-invoking the import; if persistent, check dialog construction/lifecycle code.
  4. Log which dismissal path occurred to distinguish user cancel from unexpected teardown.

Example fix

// before
None => Err(anyhow::anyhow!("Channel closed before receiving a response from dialog.")),
// after
None => {
    tracing::debug!("PDF password dialog closed without a response; aborting import");
    Ok(false)
}
Defensive patterns

Strategy: fallback

Try / catch

match dialog_response {
    Some(pwd) => import_with_password(pwd),
    None => Ok(false), // treat as user abort
}

Prevention

When it happens

Trigger: In `dialog_import_pdf_w_prefs`, the PDF password dialog is dismissed in a way that does not emit a response (window destroyed, dialog cancelled by shutdown, response sender dropped) so `pdf_password_dialog` future resolves to None.

Common situations: User closes the parent window while the password dialog is open; dialog cancelled programmatically; a bug where the dialog's FutureExt::map handling never forwards a response before teardown.

Related errors


AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08). Data as JSON: /api/errors/c5bd53d7bbf35270. Report an issue: GitHub.

Appendix: source

Thrown at crates/rnote-ui/src/dialogs/import.rs:564

                        if let Err(e) = tx_import.unbounded_send(Ok(true)) {
                            error!(
                                "PDF file imported, but failed to send signal through channel. Err: {e:?}"
                            );
                        }
                    }
                ));

                match rx_import.next().await {
                    Some(res) => res,
                    None => Err(anyhow::anyhow!(
                        "Channel closed before receiving a response from loader thread."
                    )),
                }
            } else {
                Ok(false)
            }
        }
        None => Err(anyhow::anyhow!(
            "Channel closed before receiving a response from dialog."
        )),
    }
}

/// Imports the file as Xopp with an import dialog.
///
/// Returns true when the file was imported, else false.
pub(crate) async fn dialog_import_xopp_w_prefs(
    appwindow: &RnAppWindow,
    canvas: &RnCanvas,
    input_file: gio::File,
) -> anyhow::Result<bool> {
    let builder = Builder::from_resource(
        (String::from(config::APP_IDPATH) + "ui/dialogs/import.ui").as_str(),
    );
    let dialog: adw::Dialog = builder.object("dialog_import_xopp_w_prefs").unwrap();
    let dpi_row: adw::SpinRow = builder.object("xopp_import_dpi_row").unwrap();

View on GitHub (pinned to bbc5354502)