sigoden/aichat · error
Aborted.
Error message
Aborted.
What it means
Sentinel error signaling that the SSE stream was cancelled through the shared AbortSignal (user pressed Ctrl-C or ESC) while the model response was still streaming. The handler's abort flag is checked after the send/render join completes, so this fires only for intentional user-initiated cancellation, not network or protocol failures.
Solutions
- Propagate the abort to the caller so the session returns to the prompt without retrying the request
- If a partial response was already rendered before the abort, keep it in the session history so the conversation state stays consistent
- Optionally offer a 'continue' command that re-issues the request with the accumulated partial output as context
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at src/client/common.rs:455 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09).
Data as JSON: /api/errors/607945fc809f1554.
Report an issue: GitHub.
Appendix: source
Thrown at src/client/common.rs:455
Err(err) => Err(err),
}
}
pub async fn call_chat_completions_streaming(
input: &Input,
client: &dyn Client,
abort_signal: AbortSignal,
) -> Result<(String, Vec<ToolResult>)> {
let (tx, rx) = unbounded_channel();
let mut handler = SseHandler::new(tx, abort_signal.clone());
let (send_ret, render_ret) = tokio::join!(
client.chat_completions_streaming(input, &mut handler),
render_stream(rx, client.global_config(), abort_signal.clone()),
);
if handler.abort().aborted() {
bail!("Aborted.");
}
render_ret?;
let (text, tool_calls) = handler.take();
match send_ret {
Ok(_) => {
if !text.is_empty() && !text.ends_with('\n') {
println!();
}
Ok((text, eval_tool_calls(client.global_config(), tool_calls)?))
}
Err(err) => {
if !text.is_empty() {
println!();
}
Err(err)
}View on GitHub (pinned to 82976d349a)