{"record":{"id":"99cd156f19e39744","repo":"GitoxideLabs/gitoxide","slug":"cancelled-by-user-99cd15","errorCode":null,"errorMessage":"Cancelled by user","messagePattern":"Cancelled by user","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"info","filePath":"gitoxide-core/src/repository/odb.rs","lineNumber":174,"sourceCode":"        type Error = anyhow::Error;\n\n        fn feed(&mut self, items: Self::Input) -> Result<Self::FeedProduce, Self::Error> {\n            for (id, item) in items? {\n                self.stats.consume(item);\n                if let Some(ids) = self.stats.ids.as_mut() {\n                    ids.push(id);\n                }\n            }\n            Ok(())\n        }\n\n        fn finalize(mut self) -> Result<Self::Output, Self::Error> {\n            self.stats.total_objects = self.stats.loose_objects + self.stats.packed_objects;\n            Ok(self.stats)\n        }\n    }\n\n    let cancelled = || anyhow::anyhow!(\"Cancelled by user\");\n    let object_ids = repo.objects.iter()?.filter_map(Result::ok);\n    let chunk_size = 1_000;\n    let mut stats = if gix::parallel::num_threads(thread_limit) > 1 {\n        gix::parallel::in_parallel(\n            gix::interrupt::Iter::new(\n                gix::features::iter::Chunks {\n                    inner: object_ids,\n                    size: chunk_size,\n                },\n                cancelled,\n            ),\n            thread_limit,\n            {\n                let objects = repo.objects.clone();\n                move |_| (objects.clone().into_inner(), counter)\n            },\n            |ids, (handle, counter)| {\n                let ids = ids?;","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gitoxide-core/src/repository/odb.rs#L156-L192","documentation":"The `gix odb statistics` command supports cancellation: when the user signals interruption (Ctrl-C) while iterating all objects, `gix::interrupt::Iter` short-circuits and the code raises `anyhow::anyhow!(\"Cancelled by user\")`. It is a deliberate user-interrupt error, not a library fault.","triggerScenarios":"Running `gix odb statistics` (gitoxide-core `repository::odb::statistics`) and sending SIGINT / pressing Ctrl-C while the loose or packed object scan is in progress.","commonSituations":"Users aborting long-running object counts on huge repositories; automated scripts sending signals on timeout.","solutions":["Don't send SIGINT if you need the complete statistics output","Re-run without interruption; the operation is read-only and safe to repeat","Handle this message specially in scripts to distinguish user abort from failure"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match cmd_output {\n    Err(e) if e.to_string().contains(\"Cancelled by user\") => info!(\"user aborted statistics\"),\n    Err(e) => error!(\"statistics failed: {e}\"),\n    Ok(stats) => /* ... */,\n}","preventionTips":["Avoid sending SIGINT to long-running gix commands in scripts","Use gix::interrupt::init_handler only once per process","Treat this message as a control-flow signal, not a failure"],"tags":["git","cli","interruption","cancellation"],"backgroundTag":"operation-cancelled","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}