flxzt/rnote · error · anyhow::Error

Channel closed before receiving a response from loader…

Error message

Channel closed before receiving a response from loader thread.

What it means

Thrown when the async channel (`rx_import`) used to receive the import result from the spawned PDF loader thread is dropped/closed before sending a value, so `rx_import.next().await` yields None. Indicates the loader task panicked, was cancelled, or the sender was dropped without emitting a result.

Solutions

  1. Inspect the loader thread for panics/early returns — wrap the task body so a result (including error) is always sent through the channel.
  2. Ensure `tx_import` is not dropped before the load completes (keep it alive via move into the task and send in all branches).
  3. Retry the import; if reproducible, reproduce with the specific PDF and report/fix the parser panic.
  4. Replace bare None handling with logging the loader-side error to diagnose which path dropped the sender.

Example fix

// before
match rx_import.next().await {
    Some(res) => res,
    None => Err(anyhow::anyhow!("Channel closed before receiving a response from loader thread.")),
}
// after
match rx_import.next().await {
    Some(res) => res,
    None => {
        tracing::error!("PDF loader thread ended without sending a result");
        Err(anyhow::anyhow!("Channel closed before receiving a response from loader thread."))
    }
}
// loader side: guarantee a send in every branch
gstd::panic::catch_unwind(...); tx_import.send(result).await.ok();
Defensive patterns

Strategy: try-catch

Try / catch

match rx_import.next().await {
    Some(res) => res,
    None => { tracing::error!("loader thread dropped sender"); Err(anyhow!("loader ended without result")) }
}

Prevention

When it happens

Trigger: In `dialog_import_pdf_w_prefs`, the spawned loader thread/task ends without sending on `tx_import` (panic inside PDF parsing, early return, or sender dropped), leaving `rx_import.next()` to return None.

Common situations: Loader thread panics on a malformed PDF; task aborted due to app shutdown or window close mid-import; a code change introduces a code path that drops the sender before `send`.

Related errors


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

Appendix: source

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

                            && let Err(e) = tx_import.unbounded_send(Err(e))
                        {
                            error!(
                                "Failed to load PDF, but failed to send signal through channel. Err: {e:?}"
                            );
                            return;
                        };

                        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,

View on GitHub (pinned to bbc5354502)