Skip to main content

track/utils/
error.rs

1//! Error types for the track CLI application.
2//!
3//! This module defines all error types that can occur during track operations,
4//! including database errors, JJ errors, validation errors, and user-facing error messages.
5
6use thiserror::Error;
7
8/// Main error type for the track CLI application.
9///
10/// This enum encompasses all possible errors that can occur during track operations.
11/// Each variant provides a descriptive error message and may contain additional context.
12#[derive(Error, Debug)]
13pub enum TrackError {
14    /// Database operation failed
15    #[error("Database error: {0}")]
16    Database(#[from] rusqlite::Error),
17
18    #[error("No active task. Run 'track new' or 'track switch' first.")]
19    NoActiveTask,
20
21    #[error("Task #{0} not found")]
22    TaskNotFound(i64),
23
24    #[error("Task #{0} is archived")]
25    TaskArchived(i64),
26
27    #[error("Task name cannot be empty")]
28    EmptyTaskName,
29
30    #[error("TODO content cannot be empty")]
31    EmptyTodoContent,
32
33    #[error("Scrap content cannot be empty")]
34    EmptyScrapContent,
35
36    #[error("Workspaces have uncommitted changes: {0:?}")]
37    UncommittedWorkspaces(Vec<String>),
38
39    #[error("Ticket '{0}' is already linked to task #{1}")]
40    DuplicateTicket(String, i64),
41
42    #[error("Invalid ticket ID format: {0}")]
43    InvalidTicketFormat(String),
44
45    #[error("TODO #{0} not found")]
46    TodoNotFound(i64),
47
48    #[error("Worktree #{0} not found")]
49    WorktreeNotFound(i64),
50
51    #[error("Invalid status: {0}")]
52    InvalidStatus(String),
53
54    #[error("Cannot transition from '{from}' to '{to}'")]
55    InvalidStatusTransition { from: String, to: String },
56
57    #[error("TODO cannot be reopened from '{from}'. Add a new TODO instead.")]
58    TodoReopenForbidden { from: String },
59
60    #[error("Use 'track todo done <id>' to complete a TODO (merges JJ workspace if present).")]
61    TodoCompleteRequiresDoneCommand,
62
63    #[error(
64        "Workspace was merged (bookmark: {bookmark}) but failed to mark TODO #{todo_index} as done: {detail}"
65    )]
66    TodoCompletionDbFailed {
67        todo_index: i64,
68        bookmark: String,
69        detail: String,
70    },
71
72    #[error("JJ error: {0}")]
73    Jj(String),
74
75    #[error("Path '{0}' is not a JJ repository")]
76    NotJjRepository(String),
77
78    #[error("Bookmark '{0}' already exists")]
79    BookmarkExists(String),
80
81    #[error("Invalid URL format: {0}")]
82    InvalidUrl(String),
83
84    #[error("No repositories registered for this task")]
85    NoRepositoriesRegistered,
86
87    #[error("Failed to check status for {0}")]
88    FailedRepoStatusCheck(String),
89
90    #[error("Repository {0} has pending changes in the base workspace. Please clean before sync.")]
91    RepoHasPendingChanges(String),
92
93    #[error("IO error: {0}")]
94    Io(#[from] std::io::Error),
95
96    #[error("Operation cancelled by user")]
97    #[allow(dead_code)]
98    Cancelled,
99
100    #[error("{0}")]
101    Other(String),
102}
103
104/// Convenience type alias for Results with TrackError.
105///
106/// This type is used throughout the application for operations that may fail.
107pub type Result<T> = std::result::Result<T, TrackError>;