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}