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