From 5d56427f832316ef94d7f7cf07277f560ee7b2f9 Mon Sep 17 00:00:00 2001 From: Kiril Videlov Date: Sat, 20 Jul 2024 12:54:48 +0200 Subject: [PATCH] Adds error codes for commit failures This will helps the UI better understand why a commit operation may have failed --- .../gitbutler-branch-actions/src/virtual.rs | 32 +++++++++++++------ .../tests/extra/mod.rs | 10 ++++-- crates/gitbutler-error/src/error.rs | 4 +++ 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/crates/gitbutler-branch-actions/src/virtual.rs b/crates/gitbutler-branch-actions/src/virtual.rs index 770ff58a3..7f394b3cf 100644 --- a/crates/gitbutler-branch-actions/src/virtual.rs +++ b/crates/gitbutler-branch-actions/src/virtual.rs @@ -1697,18 +1697,23 @@ pub fn commit( Some(&["../.husky"]), &mut message_buffer, ) - .context("failed to run hook")?; + .context("failed to run hook") + .context(Code::CommitHookFailed)?; if let HookResult::RunNotSuccessful { stdout, .. } = hook_result { - bail!("commit-msg hook rejected: {}", stdout.trim()); + return Err(anyhow!("commit-msg hook rejected: {}", stdout.trim()) + .context(Code::CommitHookFailed)); } let hook_result = git2_hooks::hooks_pre_commit(project_repository.repo(), Some(&["../.husky"])) - .context("failed to run hook")?; + .context("failed to run hook") + .context(Code::CommitHookFailed)?; if let HookResult::RunNotSuccessful { stdout, .. } = hook_result { - bail!("commit hook rejected: {}", stdout.trim()); + return Err( + anyhow!("commit hook rejected: {}", stdout.trim()).context(Code::CommitHookFailed) + ); } } @@ -1725,9 +1730,12 @@ pub fn commit( .find(|(branch, _)| branch.id == branch_id) .with_context(|| format!("branch {branch_id} not found"))?; - update_conflict_markers(project_repository, &files)?; + update_conflict_markers(project_repository, &files) + .context(Code::CommitMergeConflictFailure)?; - project_repository.assure_unconflicted()?; + project_repository + .assure_unconflicted() + .context(Code::CommitMergeConflictFailure)?; let tree_oid = if let Some(ownership) = ownership { let files = files.into_iter().filter_map(|(filepath, hunks)| { @@ -1766,8 +1774,9 @@ pub fn commit( .context(format!("failed to find tree {:?}", tree_oid))?; // now write a commit, using a merge parent if it exists - let extra_merge_parent = - conflicts::merge_parent(project_repository).context("failed to get merge parent")?; + let extra_merge_parent = conflicts::merge_parent(project_repository) + .context("failed to get merge parent") + .context(Code::CommitMergeConflictFailure)?; let commit_oid = match extra_merge_parent { Some(merge_parent) => { @@ -1780,7 +1789,9 @@ pub fn commit( &[&parent_commit, &merge_parent], None, )?; - conflicts::clear(project_repository).context("failed to clear conflicts")?; + conflicts::clear(project_repository) + .context("failed to clear conflicts") + .context(Code::CommitMergeConflictFailure)?; commit_oid } None => project_repository.commit(message, &tree, &[&parent_commit], None)?, @@ -1788,7 +1799,8 @@ pub fn commit( if run_hooks { git2_hooks::hooks_post_commit(project_repository.repo(), Some(&["../.husky"])) - .context("failed to run hook")?; + .context("failed to run hook") + .context(Code::CommitHookFailed)?; } let vb_state = project_repository.project().virtual_branches(); diff --git a/crates/gitbutler-branch-actions/tests/extra/mod.rs b/crates/gitbutler-branch-actions/tests/extra/mod.rs index afd658726..9632c5bac 100644 --- a/crates/gitbutler-branch-actions/tests/extra/mod.rs +++ b/crates/gitbutler-branch-actions/tests/extra/mod.rs @@ -2163,7 +2163,10 @@ fn pre_commit_hook_rejection() -> Result<()> { let res = commit(project_repository, branch1_id, "test commit", None, true); let err = res.unwrap_err(); - assert_eq!(err.to_string(), "commit hook rejected: rejected"); + assert_eq!( + err.source().unwrap().to_string(), + "commit hook rejected: rejected" + ); Ok(()) } @@ -2256,7 +2259,10 @@ fn commit_msg_hook_rejection() -> Result<()> { let res = commit(project_repository, branch1_id, "test commit", None, true); let err = res.unwrap_err(); - assert_eq!(err.to_string(), "commit-msg hook rejected: rejected"); + assert_eq!( + err.source().unwrap().to_string(), + "commit-msg hook rejected: rejected" + ); Ok(()) } diff --git a/crates/gitbutler-error/src/error.rs b/crates/gitbutler-error/src/error.rs index b8a7477ea..136699c8e 100644 --- a/crates/gitbutler-error/src/error.rs +++ b/crates/gitbutler-error/src/error.rs @@ -132,6 +132,8 @@ pub enum Code { ProjectGitAuth, DefaultTargetNotFound, CommitSigningFailed, + CommitHookFailed, + CommitMergeConflictFailure, } impl std::fmt::Display for Code { @@ -142,6 +144,8 @@ impl std::fmt::Display for Code { Code::ProjectGitAuth => "errors.projects.git.auth", Code::DefaultTargetNotFound => "errors.projects.default_target.not_found", Code::CommitSigningFailed => "errors.commit.signing_failed", + Code::CommitHookFailed => "errors.commit.hook_failed", + Code::CommitMergeConflictFailure => "errors.commit.merge_conflict_failure", }; f.write_str(code) }