Skip to main content

zeph_worktree/
error.rs

1// SPDX-License-Identifier: MIT
2//! Error types for the `zeph-worktree` crate.
3
4use std::path::PathBuf;
5
6#[non_exhaustive]
7/// All errors that `zeph-worktree` can produce.
8///
9/// Every variant is designed so that the `Display` message is safe to show to the
10/// user; raw git stderr is kept in [`WorktreeError::GitCommand`]'s `stderr` field
11/// and must only be logged at `DEBUG` level — never forwarded to the user.
12#[derive(Debug, thiserror::Error)]
13pub enum WorktreeError {
14    /// The working directory is not inside a git repository.
15    #[error("not inside a git repository")]
16    NotAGitRepo,
17
18    /// A git sub-command exited with a non-zero status.
19    ///
20    /// `op` names the operation (e.g. `"fetch"`, `"worktree add"`).
21    /// `stderr` is raw git output — log at `DEBUG`, never surface to the user.
22    #[error("git command `{op}` failed")]
23    GitCommand {
24        /// The git operation that failed (e.g. `"fetch"`, `"worktree add"`).
25        op: String,
26        /// Raw stderr from git — for diagnostic logging only.
27        stderr: String,
28    },
29
30    /// The computed worktree path already exists on disk.
31    #[error("worktree path already exists: {0}")]
32    PathExists(PathBuf),
33
34    /// The default branch could not be resolved.
35    ///
36    /// Emitted when `config.default_branch` is empty and
37    /// `git symbolic-ref refs/remotes/origin/HEAD` fails.
38    #[error("cannot resolve default branch: attempted {attempted}")]
39    BaseRefUnresolved {
40        /// Description of what was attempted before giving up.
41        attempted: String,
42    },
43
44    /// The `subagent_id` value contains characters that are not allowed in a
45    /// git branch component.
46    #[error("invalid branch name component: {0}")]
47    InvalidBranchName(String),
48
49    /// The canonicalised worktree root resolves to a path outside the repository.
50    #[error("worktree root resolves outside the repository: {0}")]
51    RootOutsideRepo(PathBuf),
52
53    /// An I/O error propagated from the OS or `std::fs`.
54    #[error(transparent)]
55    Io(#[from] std::io::Error),
56
57    /// A `create()` call was refused because `worktree.max_worktrees` would be
58    /// reached or exceeded.
59    ///
60    /// `current` is the number of git-registered secondary worktrees under `root`
61    /// at the time of the check (including worktrees owned by other, concurrently
62    /// running zeph sessions); `max` is the configured `max_worktrees` limit. This
63    /// is a soft, best-effort cap — see
64    /// [`WorktreeManager::create`](crate::WorktreeManager::create)'s doc comment
65    /// for the TOCTOU caveat under concurrent sessions.
66    #[error(
67        "worktree limit reached ({current}/{max}); run `zeph worktree clean` or raise \
68         `worktree.max_worktrees`"
69    )]
70    QuotaExceeded {
71        /// Number of git-registered secondary worktrees under `root` at check time.
72        current: usize,
73        /// The configured `worktree.max_worktrees` limit.
74        max: usize,
75    },
76}