Skip to main content

gitu/
error.rs

1use std::{fmt::Display, io, string};
2
3#[derive(Debug)]
4pub enum Error {
5    StashList(git2::Error),
6    ReadLog(git2::Error),
7    OpenRepo(git2::Error),
8    FindGitDir(io::Error),
9    Term(io::Error),
10    GitDirUtf8(string::FromUtf8Error),
11    Config(Box<figment::Error>),
12    EditConfig(String),
13    Bindings { bad_key_bindings: Vec<String> },
14    FileWatcher(notify::Error),
15    ReadRebaseStatusFile(io::Error),
16    ReadRebaseTodo(io::Error),
17    ReadPipedInput(io::Error),
18    PagerWithoutInput,
19    WriteRebaseTodo(io::Error),
20    ReadBranchName(io::Error),
21    BranchNameUtf8(Utf8Error),
22    GitDiff(io::Error),
23    GitDiffUtf8(string::FromUtf8Error),
24    GitShow(io::Error),
25    GitShowUtf8(string::FromUtf8Error),
26    GitShowMeta(git2::Error),
27    NotOnBranch,
28    GetHead(git2::Error),
29    CurrentBranchName(git2::Error),
30    GetCurrentBranchUpstream(git2::Error),
31    GetCurrentBranchUpstreamUtf8(Utf8Error),
32    RemoteNameUtf8(Utf8Error),
33    CannotDeleteCurrentBranch,
34    BranchNameRequired,
35    IsBranchMerged(git2::Error),
36    GetRemote(git2::Error),
37    ReadGitConfig(git2::Error),
38    ReadGitConfigUtf8(Utf8Error),
39    DeleteGitConfig(git2::Error),
40    SetGitConfig(git2::Error),
41    RemoteHasNoName,
42    ReadOid(git2::Error),
43    ArgMustBePositiveNumber,
44    ArgInvalidRegex(regex::Error),
45    Clipboard(arboard::Error),
46    FindGitRev(git2::Error),
47    NoEditorSet,
48    GitStatus(git2::Error),
49    CmdAlreadyRunning,
50    StashWorkTreeEmpty,
51    CouldntAwaitCmd(io::Error),
52    NoRepoWorkdir,
53    SpawnCmd(io::Error),
54    CmdBadExit(String, Option<i32>),
55    CouldntReadCmdOutput(io::Error),
56    ListGitReferences(git2::Error),
57    OpenLogFile(io::Error),
58    PromptAborted,
59    ReadPromptHistory(io::Error),
60    WritePromptHistory(io::Error),
61    NoMoreEvents,
62    CannotSpinoffCurrentBranch,
63    SpinoffBranchExists(String),
64    DoesBranchExist(git2::Error),
65    GetBranchName(git2::Error),
66    BaseCommitOid,
67    UpstreamCommitOid,
68    GitBlame(io::Error),
69    NoSearchMatch(String),
70    NoPreviousSearch,
71    InvalidSearchRegex(regex::Error),
72    EditedCommandQuotes,
73    EditedCommandFixed,
74    EditedCommandWrites(String),
75    GitRefusedTheCommand(String),
76}
77
78impl std::error::Error for Error {}
79
80impl Display for Error {
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82        match self {
83            Error::StashList(e) => f.write_fmt(format_args!("Couldn't list stash: {e}")),
84            Error::ReadLog(e) => f.write_fmt(format_args!("Couldn't read log: {e}")),
85            Error::ReadPipedInput(e) => {
86                f.write_fmt(format_args!("Couldn't read the piped input: {e}"))
87            }
88            Error::PagerWithoutInput => {
89                f.write_str("--pager expects a patch on stdin, e.g. `git show | gitu --pager`")
90            }
91            Error::ReadRebaseTodo(e) => {
92                f.write_fmt(format_args!("Couldn't read the rebase todo list: {e}"))
93            }
94            Error::WriteRebaseTodo(e) => {
95                f.write_fmt(format_args!("Couldn't write the rebase todo list: {e}"))
96            }
97            Error::OpenRepo(e) => match e.code() {
98                git2::ErrorCode::NotFound => f.write_str("No .git found in the current directory"),
99                _ => f.write_fmt(format_args!("Couldn't open repo: {e:?}")),
100            },
101            Error::FindGitDir(e) => f.write_fmt(format_args!("Couldn't find git directory: {}", e)),
102            Error::Term(e) => f.write_fmt(format_args!("Terminal error: {}", e)),
103            Error::GitDirUtf8(_e) => f.write_str("Git directory not valid UTF-8"),
104            Error::Config(e) => f.write_fmt(format_args!("Configuration error: {e}")),
105            Error::EditConfig(e) => {
106                f.write_fmt(format_args!("Couldn't save to the config file: {e}"))
107            }
108            Error::Bindings { bad_key_bindings } => {
109                let mut error_string = String::from("Errors while parsing key bindings:");
110                for item in bad_key_bindings {
111                    error_string.push_str(&format!("\n{item}"));
112                }
113                f.write_fmt(format_args!("{error_string}"))
114            }
115            Error::FileWatcher(e) => f.write_fmt(format_args!("File watcher error: {e}")),
116            Error::ReadRebaseStatusFile(e) => {
117                f.write_fmt(format_args!("Couldn't read rebase status file: {e}"))
118            }
119            Error::ReadBranchName(e) => f.write_fmt(format_args!("Couldn't read branch name: {e}")),
120            Error::BranchNameUtf8(_e) => f.write_str("Branch name error"),
121            Error::GitDiff(e) => f.write_fmt(format_args!("Git diff error: {e}")),
122            Error::GitDiffUtf8(e) => {
123                f.write_fmt(format_args!("Git diff output is not valid UTF-8: {e}"))
124            }
125            Error::GitShow(e) => f.write_fmt(format_args!("Git show error: {e}")),
126            Error::GitShowUtf8(e) => {
127                f.write_fmt(format_args!("Git show output is not valid UTF-8: {e}"))
128            }
129            Error::GitShowMeta(e) => f.write_fmt(format_args!("Git show metadata error: {e}")),
130            Error::NotOnBranch => f.write_str("Head is not a branch"),
131            Error::GetHead(e) => f.write_fmt(format_args!("Couldn't get HEAD: {e}")),
132            Error::CurrentBranchName(e) => {
133                f.write_fmt(format_args!("Couldn't get current branch name: {e}"))
134            }
135            Error::GetCurrentBranchUpstream(e) => {
136                f.write_fmt(format_args!("Couldn't get current branch upstream: {e}"))
137            }
138            Error::GetCurrentBranchUpstreamUtf8(_e) => {
139                f.write_str("Current branch upstream is not valid UTF-8")
140            }
141            Error::RemoteNameUtf8(_e) => f.write_str("Remote name is not valid UTF-8"),
142            Error::CannotDeleteCurrentBranch => f.write_str("Cannot delete current branch"),
143            Error::BranchNameRequired => f.write_str("Branch name required"),
144            Error::IsBranchMerged(e) => {
145                f.write_fmt(format_args!("Couldn't check if branch is merged: {e}"))
146            }
147            Error::GetRemote(e) => f.write_fmt(format_args!("Couldn't get remote: {e}")),
148            Error::ReadGitConfig(e) => f.write_fmt(format_args!("Couldn't read git config: {e}")),
149            Error::ReadGitConfigUtf8(_e) => f.write_str("Git config is not valid UTF-8"),
150            Error::DeleteGitConfig(e) => {
151                f.write_fmt(format_args!("Couldn't delete git config: {e}"))
152            }
153            Error::SetGitConfig(e) => f.write_fmt(format_args!("Couldn't set git config: {e}")),
154            Error::RemoteHasNoName => f.write_str("Remote has no name"),
155            Error::ReadOid(e) => f.write_fmt(format_args!("Couldn't read OID: {e}")),
156            Error::ArgMustBePositiveNumber => f.write_str("Value must be a number greater than 0"),
157            Error::ArgInvalidRegex(e) => f.write_fmt(format_args!("Invalid regex: {e}")),
158            Error::Clipboard(e) => f.write_fmt(format_args!("Clipboard error: {e}")),
159            Error::FindGitRev(e) => f.write_fmt(format_args!("Couldn't find git revision: {e}")),
160            Error::NoEditorSet => f.write_fmt(format_args!(
161                "No editor environment variable set ({})",
162                crate::ops::show::EDITOR_VARS.join(", ")
163            )),
164            Error::GitStatus(e) => f.write_fmt(format_args!("Git status error: {e}")),
165            Error::CmdAlreadyRunning => f.write_str("A command is already running"),
166            Error::StashWorkTreeEmpty => f.write_str("Cannot stash: working tree is empty"),
167            Error::CouldntAwaitCmd(e) => f.write_fmt(format_args!("Couldn't await command: {e}")),
168            Error::NoRepoWorkdir => f.write_str("No repository working directory"),
169            Error::SpawnCmd(e) => f.write_fmt(format_args!("Failed to spawn command: {e}")),
170            Error::CmdBadExit(args, code) => f.write_fmt(format_args!(
171                "'{}' exited with code: {}",
172                args,
173                code.map(|c| c.to_string())
174                    .unwrap_or_else(|| "".to_string())
175            )),
176            Error::CouldntReadCmdOutput(e) => {
177                f.write_fmt(format_args!("Couldn't read command output: {e}"))
178            }
179            Error::ListGitReferences(e) => {
180                f.write_fmt(format_args!("Couldn't list git references: {e}"))
181            }
182            Error::OpenLogFile(e) => f.write_fmt(format_args!("Couldn't open log file: {e}")),
183            Error::PromptAborted => f.write_str("Aborted"),
184            Error::ReadPromptHistory(e) => {
185                f.write_fmt(format_args!("Couldn't read prompt history: {e}"))
186            }
187            Error::WritePromptHistory(e) => {
188                f.write_fmt(format_args!("Couldn't write prompt history: {e}"))
189            }
190            Error::NoMoreEvents => unimplemented!(),
191            Error::CannotSpinoffCurrentBranch => f.write_str("Cannot spin-off current branch"),
192            Error::SpinoffBranchExists(new_branch_name) => f.write_fmt(format_args!(
193                "Cannot spin-off {new_branch_name}. It already exists"
194            )),
195            Error::DoesBranchExist(e) => {
196                f.write_fmt(format_args!("Couldn't check if branch exists: {}", e))
197            }
198            Error::GetBranchName(e) => f.write_fmt(format_args!("Couldn't get branch name: {}", e)),
199            Error::BaseCommitOid => f.write_str("Could not resolve OID of base commit"),
200            Error::UpstreamCommitOid => {
201                f.write_str("Could not resolve OID of upstream branch commit")
202            }
203            Error::GitBlame(e) => f.write_fmt(format_args!("Git blame error: {e}")),
204            Error::NoSearchMatch(query) => f.write_fmt(format_args!("No match: {query}")),
205            Error::NoPreviousSearch => f.write_str("No previous search"),
206            Error::InvalidSearchRegex(e) => f.write_fmt(format_args!("Invalid search: {e}")),
207            Error::EditedCommandQuotes => f.write_str("Unbalanced quotes"),
208            Error::EditedCommandFixed => f.write_str(
209                "Only git's arguments can be edited, not the program or git's own options",
210            ),
211            Error::EditedCommandWrites(subcommand) => f.write_fmt(format_args!(
212                "gitu re-runs this command on every refresh, so it must only report: {subcommand}"
213            )),
214            Error::GitRefusedTheCommand(stderr) => f.write_str(stderr),
215        }
216    }
217}
218
219#[derive(Debug)]
220pub enum Utf8Error {
221    Str(std::str::Utf8Error),
222    String(string::FromUtf8Error),
223}
224
225impl std::error::Error for Utf8Error {}
226
227impl Display for Utf8Error {
228    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
229        f.write_str("not valid UTF-8")
230    }
231}