sigoden/aichat · info · anyhow::Error
Aborted!
Error message
Aborted!
What it means
abortable_run_with_spinner_rx races the user's task against Ctrl+C (tokio::signal::ctrl_c). When the user presses Ctrl+C, the function sets the abort signal, notifies the spinner, and bails with 'Aborted!'. It signals intentional user-interrupted cancellation rather than an unexpected failure.
Solutions
- Re-run the command and let it finish without pressing Ctrl+C
- Check for network/API slowness that tempts cancellation (timeouts, connectivity)
- Handle the aborted result gracefully in scripts and re-invoke when needed
- Reduce workload size (fewer documents, smaller batches) so runs complete quickly
Defensive patterns
Strategy: try-catch
Try / catch
match abortable_run_with_spinner_rx(task, spinner, signal).await {
Err(e) if e.to_string() == "Aborted!" => {
eprintln!("operation cancelled by user (Ctrl+C)");
std::process::exit(130); // conventional SIGINT exit code
}
other => other?,
} Prevention
- Avoid pressing Ctrl+C mid-run; prefer commands that checkpoint/resume
- Use timeouts/retries for flaky network operations instead of manual cancels
- In scripts, treat 'Aborted!' as exit code 130 and re-run idempotent steps
When it happens
Trigger: Pressing Ctrl+C while a task wrapped in the abortable spinner is running (e.g. during init or refresh_document_paths long-running operations).
Common situations: User cancels a long network request, model stream, or document refresh; impatient re-press of Ctrl+C during any spinner-wrapped command.
Related errors
AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09).
Data as JSON: /api/errors/b6f03872ac797b1c.
Report an issue: GitHub.
Appendix: source
Thrown at src/utils/spinner.rs:159
task: F,
spinner_rx: UnboundedReceiver<SpinnerEvent>,
abort_signal: AbortSignal,
) -> Result<T>
where
F: Future<Output = Result<T>>,
{
if *IS_STDOUT_TERMINAL {
let (done_tx, done_rx) = oneshot::channel();
let run_task = async {
tokio::select! {
ret = task => {
let _ = done_tx.send(());
ret
}
_ = tokio::signal::ctrl_c() => {
abort_signal.set_ctrlc();
let _ = done_tx.send(());
bail!("Aborted!")
},
_ = wait_abort_signal(&abort_signal) => {
let _ = done_tx.send(());
bail!("Aborted.");
},
}
};
let (task_ret, spinner_ret) = tokio::join!(
run_task,
run_abortable_spinner(spinner_rx, done_rx, abort_signal.clone())
);
spinner_ret?;
task_ret
} else {
task.await
}
}
View on GitHub (pinned to 82976d349a)