crates/substrate/gix-ref-store/src/error.rs
error.rshistorycomment on this file
| 1 | //! The error type every `gix-ref-store` operation returns. |
| 2 | |
| 3 | use std::path::PathBuf; |
| 4 | |
| 5 | /// Everything that can go wrong reading or writing through a [`crate::RefStore`]. |
| 6 | /// |
| 7 | /// Every variant is a backend I/O or protocol failure; a *rejected* |
| 8 | /// compare-and-swap is not an error at all, since a stale precondition is |
| 9 | /// an expected outcome, not a fault. See [`crate::TxOutcome::Rejected`]. |
| 10 | #[derive(Debug, thiserror::Error)] |
| 11 | pub enum Error { |
| 12 | /// Opening the on-disk repository the store reads and writes through |
| 13 | /// failed. The caller should check that `path` names a git repository |
| 14 | /// (or its `.git` directory) and that the process has permission to |
| 15 | /// read it. |
| 16 | #[error("failed to open the repository at {path}: {source}")] |
| 17 | Open { |
| 18 | /// The path that was passed to [`crate::LooseRefStore::open`]. |
| 19 | path: PathBuf, |
| 20 | /// The underlying gitoxide error. |
| 21 | #[source] |
| 22 | source: Box<gix::open::Error>, |
| 23 | }, |
| 24 | |
| 25 | /// A refname string failed gitoxide's own validation (for example, it |
| 26 | /// contained a `..` component or a disallowed character). The caller |
| 27 | /// should reject the name before offering it to a [`crate::RefStore`]. |
| 28 | #[error("invalid reference name: {0}")] |
| 29 | InvalidName(#[from] gix::validate::reference::name::Error), |
| 30 | |
| 31 | /// A read (lookup, peel, or iteration) against the backend failed for |
| 32 | /// a reason other than the ref simply not existing. This wraps |
| 33 | /// whatever gitoxide's own read path reported; the caller should treat |
| 34 | /// it as an I/O-class failure, not a CAS rejection. |
| 35 | #[error("ref-store read failed: {0}")] |
| 36 | Read(#[source] Box<dyn std::error::Error + Send + Sync + 'static>), |
| 37 | |
| 38 | /// A [`crate::RefStore::transaction`] call failed outright — a lock |
| 39 | /// could not be acquired, the on-disk state could not be parsed, or |
| 40 | /// similar — as distinct from a clean CAS rejection, which is |
| 41 | /// reported as `Ok(TxOutcome::Rejected { .. })` rather than this |
| 42 | /// variant. |
| 43 | #[error("ref transaction failed: {0}")] |
| 44 | Transaction(#[from] gix::reference::edit::Error), |
| 45 | |
| 46 | /// The store's own serialization lock (see `loose` module docs for why |
| 47 | /// it exists) could not be acquired within its timeout — most likely |
| 48 | /// another `transaction()` call is legitimately in flight and slow, or |
| 49 | /// a prior process crashed while holding it and left the lock file |
| 50 | /// behind. The caller should retry, and an operator investigating a |
| 51 | /// permanently-stuck store should look for a stale lock file in the |
| 52 | /// repository's git directory. |
| 53 | #[error("could not acquire the ref-store transaction lock: {0}")] |
| 54 | StoreLock(#[source] gix_lock::acquire::Error), |
| 55 | } |
| 56 | |
| 57 | /// The `Result` alias every `gix-ref-store` operation returns. |
| 58 | pub type Result<T> = std::result::Result<T, Error>; |