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
- Inspect the loader thread for panics/early returns — wrap the task body so a result (including error) is always sent through the channel.
- Ensure `tx_import` is not dropped before the load completes (keep it alive via move into the task and send in all branches).
- Retry the import; if reproducible, reproduce with the specific PDF and report/fix the parser panic.
- 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
- Always send a Result through the channel in every loader branch
- Catch panics in the loader task and convert them to Err results
- Keep the sender alive for the whole task lifetime (move into closure)
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
- Channel closed before receiving a response from dialog.
- PdfImportPagesType try_from
- PdfImportPageSpacing try_from
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)