Skip to content

Commit 49987df

Browse files
committed
Throw NotFound and CannotDereference Exceptions
This change is to throw more specific exceptions in several cases when possible. If an object cannot be found, throw a more specific NotFoundException. If an object exists but cannot be dereferenced to its desired type, then throw a CannotDereferenceException.
1 parent 0e5bfbc commit 49987df

17 files changed

+160
-24
lines changed

Diff for: LibGit2Sharp.Tests/BlameFixture.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public void CanBlameFromADifferentCommit()
3434
using (var repo = new Repository(MergedTestRepoWorkingDirPath))
3535
{
3636
// File doesn't exist at HEAD
37-
Assert.Throws<LibGit2SharpException>(() => repo.Blame("ancestor-only.txt"));
37+
Assert.Throws<NotFoundException>(() => repo.Blame("ancestor-only.txt"));
3838

3939
var blame = repo.Blame("ancestor-only.txt", new BlameOptions { StartingAt = "9107b30" });
4040
Assert.Equal(1, blame.Count());

Diff for: LibGit2Sharp.Tests/BranchFixture.cs

+7-7
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,9 @@ public void CreatingABranchFromANonCommitObjectThrows()
241241
using (var repo = new Repository(BareTestRepoPath))
242242
{
243243
const string name = "sorry-dude-i-do-not-do-blobs-nor-trees";
244-
Assert.Throws<LibGit2SharpException>(() => repo.CreateBranch(name, "refs/tags/point_to_blob"));
245-
Assert.Throws<LibGit2SharpException>(() => repo.CreateBranch(name, "53fc32d"));
246-
Assert.Throws<LibGit2SharpException>(() => repo.CreateBranch(name, "0266163"));
244+
Assert.Throws<CannotDereferenceException>(() => repo.CreateBranch(name, "refs/tags/point_to_blob"));
245+
Assert.Throws<CannotDereferenceException>(() => repo.CreateBranch(name, "53fc32d"));
246+
Assert.Throws<CannotDereferenceException>(() => repo.CreateBranch(name, "0266163"));
247247
}
248248
}
249249

@@ -252,7 +252,7 @@ public void CreatingBranchWithUnknownNamedTargetThrows()
252252
{
253253
using (var repo = new Repository(BareTestRepoPath))
254254
{
255-
Assert.Throws<LibGit2SharpException>(() => repo.Branches.Add("my_new_branch", "my_old_branch"));
255+
Assert.Throws<NotFoundException>(() => repo.Branches.Add("my_new_branch", "my_old_branch"));
256256
}
257257
}
258258

@@ -261,8 +261,8 @@ public void CreatingBranchWithUnknownShaTargetThrows()
261261
{
262262
using (var repo = new Repository(BareTestRepoPath))
263263
{
264-
Assert.Throws<LibGit2SharpException>(() => repo.Branches.Add("my_new_branch", Constants.UnknownSha));
265-
Assert.Throws<LibGit2SharpException>(() => repo.Branches.Add("my_new_branch", Constants.UnknownSha.Substring(0, 7)));
264+
Assert.Throws<NotFoundException>(() => repo.Branches.Add("my_new_branch", Constants.UnknownSha));
265+
Assert.Throws<NotFoundException>(() => repo.Branches.Add("my_new_branch", Constants.UnknownSha.Substring(0, 7)));
266266
}
267267
}
268268

@@ -707,7 +707,7 @@ public void SetTrackedBranchForUnreasolvableRemoteThrows()
707707

708708
Branch trackedBranch = repo.Branches[trackedBranchName];
709709

710-
Assert.Throws<LibGit2SharpException>(() => repo.Branches.Update(branch,
710+
Assert.Throws<NotFoundException>(() => repo.Branches.Update(branch,
711711
b => b.TrackedBranch = trackedBranch.CanonicalName));
712712
}
713713
}

Diff for: LibGit2Sharp.Tests/CheckoutFixture.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ public void CheckingOutANonExistingBranchThrows()
381381
{
382382
using (var repo = new Repository(StandardTestRepoWorkingDirPath))
383383
{
384-
Assert.Throws<LibGit2SharpException>(() => repo.Checkout("i-do-not-exist"));
384+
Assert.Throws<NotFoundException>(() => repo.Checkout("i-do-not-exist"));
385385
}
386386
}
387387

@@ -891,7 +891,7 @@ public void CheckoutLowerCasedHeadThrows()
891891
{
892892
using (var repo = new Repository(StandardTestRepoWorkingDirPath))
893893
{
894-
Assert.Throws<LibGit2SharpException>(() => repo.Checkout("head"));
894+
Assert.Throws<NotFoundException>(() => repo.Checkout("head"));
895895
}
896896
}
897897

Diff for: LibGit2Sharp.Tests/CommitFixture.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ public void QueryingTheCommitHistoryWithUnknownShaOrInvalidEntryPointThrows()
101101
{
102102
using (var repo = new Repository(BareTestRepoPath))
103103
{
104-
Assert.Throws<LibGit2SharpException>(() => repo.Commits.QueryBy(new CommitFilter { Since = Constants.UnknownSha }).Count());
105-
Assert.Throws<LibGit2SharpException>(() => repo.Commits.QueryBy(new CommitFilter { Since = "refs/heads/deadbeef" }).Count());
104+
Assert.Throws<NotFoundException>(() => repo.Commits.QueryBy(new CommitFilter { Since = Constants.UnknownSha }).Count());
105+
Assert.Throws<NotFoundException>(() => repo.Commits.QueryBy(new CommitFilter { Since = "refs/heads/deadbeef" }).Count());
106106
Assert.Throws<ArgumentNullException>(() => repo.Commits.QueryBy(new CommitFilter { Since = null }).Count());
107107
}
108108
}
@@ -115,8 +115,8 @@ public void QueryingTheCommitHistoryFromACorruptedReferenceThrows()
115115
{
116116
CreateCorruptedDeadBeefHead(repo.Info.Path);
117117

118-
Assert.Throws<LibGit2SharpException>(() => repo.Commits.QueryBy(new CommitFilter { Since = repo.Branches["deadbeef"] }).Count());
119-
Assert.Throws<LibGit2SharpException>(() => repo.Commits.QueryBy(new CommitFilter { Since = repo.Refs["refs/heads/deadbeef"] }).Count());
118+
Assert.Throws<NotFoundException>(() => repo.Commits.QueryBy(new CommitFilter { Since = repo.Branches["deadbeef"] }).Count());
119+
Assert.Throws<NotFoundException>(() => repo.Commits.QueryBy(new CommitFilter { Since = repo.Refs["refs/heads/deadbeef"] }).Count());
120120
}
121121
}
122122

Diff for: LibGit2Sharp.Tests/ReferenceFixture.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public void CreatingADirectReferenceWithARevparseSpecPointingAtAnUnknownObjectFa
7373
string path = CloneBareTestRepo();
7474
using (var repo = new Repository(path))
7575
{
76-
Assert.Throws<LibGit2SharpException>(() => repo.Refs.Add(name, "master^42"));
76+
Assert.Throws<NotFoundException>(() => repo.Refs.Add(name, "master^42"));
7777
}
7878
}
7979

@@ -596,7 +596,7 @@ public void UpdatingADirectReferenceTargetWithARevparsePointingAtAnUnknownObject
596596
{
597597
using (var repo = new Repository(BareTestRepoPath))
598598
{
599-
Assert.Throws<LibGit2SharpException>(() => repo.Refs.UpdateTarget(repo.Refs["refs/heads/master"], "refs/heads/nope"));
599+
Assert.Throws<NotFoundException>(() => repo.Refs.UpdateTarget(repo.Refs["refs/heads/master"], "refs/heads/nope"));
600600
}
601601
}
602602

Diff for: LibGit2Sharp.Tests/ResetHeadFixture.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ public void ResettingWithBadParamsThrows()
7070
Assert.Throws<ArgumentNullException>(() => repo.Reset(ResetMode.Soft, (string)null));
7171
Assert.Throws<ArgumentNullException>(() => repo.Reset(ResetMode.Soft, (Commit)null));
7272
Assert.Throws<ArgumentException>(() => repo.Reset(ResetMode.Soft, ""));
73-
Assert.Throws<LibGit2SharpException>(() => repo.Reset(ResetMode.Soft, Constants.UnknownSha));
74-
Assert.Throws<LibGit2SharpException>(() => repo.Reset(ResetMode.Soft, repo.Head.Tip.Tree.Sha));
73+
Assert.Throws<NotFoundException>(() => repo.Reset(ResetMode.Soft, Constants.UnknownSha));
74+
Assert.Throws<CannotDereferenceException>(() => repo.Reset(ResetMode.Soft, repo.Head.Tip.Tree.Sha));
7575
}
7676
}
7777

Diff for: LibGit2Sharp.Tests/TagFixture.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ public void CreatingATagForAnUnknowReferenceThrows()
257257
{
258258
using (var repo = new Repository(BareTestRepoPath))
259259
{
260-
Assert.Throws<LibGit2SharpException>(() => repo.ApplyTag("mytagnorev", "aaaaaaaaaaa"));
260+
Assert.Throws<NotFoundException>(() => repo.ApplyTag("mytagnorev", "aaaaaaaaaaa"));
261261
}
262262
}
263263

@@ -267,7 +267,7 @@ public void CreatingATagForAnUnknowObjectIdThrows()
267267
{
268268
using (var repo = new Repository(BareTestRepoPath))
269269
{
270-
Assert.Throws<LibGit2SharpException>(() => repo.ApplyTag("mytagnorev", Constants.UnknownSha));
270+
Assert.Throws<NotFoundException>(() => repo.ApplyTag("mytagnorev", Constants.UnknownSha));
271271
}
272272
}
273273

@@ -497,7 +497,7 @@ public void AddTagWithNotExistingTargetThrows()
497497
{
498498
using (var repo = new Repository(BareTestRepoPath))
499499
{
500-
Assert.Throws<LibGit2SharpException>(() => repo.Tags.Add("test_tag", Constants.UnknownSha, signatureTim, "message"));
500+
Assert.Throws<NotFoundException>(() => repo.Tags.Add("test_tag", Constants.UnknownSha, signatureTim, "message"));
501501
}
502502
}
503503

@@ -608,7 +608,7 @@ public void RemovingAnUnknownTagShouldFail()
608608
{
609609
using (var repo = new Repository(BareTestRepoPath))
610610
{
611-
Assert.Throws<LibGit2SharpException>(() => repo.Tags.Remove("unknown-tag"));
611+
Assert.Throws<NotFoundException>(() => repo.Tags.Remove("unknown-tag"));
612612
}
613613
}
614614

Diff for: LibGit2Sharp/AmbiguousSpecificationException.cs

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Runtime.Serialization;
3+
using LibGit2Sharp.Core;
34

45
namespace LibGit2Sharp
56
{
@@ -44,5 +45,10 @@ protected AmbiguousSpecificationException(SerializationInfo info, StreamingConte
4445
: base(info, context)
4546
{
4647
}
48+
49+
internal AmbiguousSpecificationException(string message, GitErrorCode code, GitErrorCategory category)
50+
: base(message, code, category)
51+
{
52+
}
4753
}
4854
}

Diff for: LibGit2Sharp/Blob.cs

+15
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ internal Blob(Repository repo, ObjectId id)
2525
lazyIsBinary = GitObjectLazyGroup.Singleton(repo, id, Proxy.git_blob_is_binary);
2626
}
2727

28+
/// <summary>
29+
/// A blob cannot be dereferenced to a commit - throws or returns null.
30+
/// </summary>
31+
/// <param name="throwsIfCanNotBeDereferencedToACommit"></param>
32+
/// <returns></returns>
33+
internal override Commit DereferenceToCommit(bool throwsIfCanNotBeDereferencedToACommit)
34+
{
35+
if (throwsIfCanNotBeDereferencedToACommit)
36+
{
37+
throw new CannotDereferenceException("Cannot dereference a blob object to a commit.");
38+
}
39+
40+
return null;
41+
}
42+
2843
/// <summary>
2944
/// Gets the size in bytes of the raw content of a blob.
3045
/// </summary>

Diff for: LibGit2Sharp/CannotDereferenceException.cs

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using System.Runtime.Serialization;
3+
4+
namespace LibGit2Sharp
5+
{
6+
/// <summary>
7+
/// The exception that is thrown when a GitObject cannot be dereferenced to the desired type.
8+
/// </summary>
9+
[Serializable]
10+
public class CannotDereferenceException : LibGit2SharpException
11+
{
12+
/// <summary>
13+
/// Initializes a new instance of the <see cref="CannotDereferenceException"/> class.
14+
/// </summary>
15+
public CannotDereferenceException()
16+
{
17+
}
18+
19+
/// <summary>
20+
/// Initializes a new instance of the <see cref="CannotDereferenceException"/> class with a specified error message.
21+
/// </summary>
22+
/// <param name="message">A message that describes the error.</param>
23+
public CannotDereferenceException(string message)
24+
: base(message)
25+
{
26+
}
27+
28+
/// <summary>
29+
/// Initializes a new instance of the <see cref="CannotDereferenceException"/> class with a specified error message and a reference to the inner exception that is the cause of this exception.
30+
/// </summary>
31+
/// <param name="message">The error message that explains the reason for the exception.</param>
32+
/// <param name="innerException">The exception that is the cause of the current exception. If the <paramref name="innerException"/> parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception.</param>
33+
public CannotDereferenceException(string message, Exception innerException)
34+
: base(message, innerException)
35+
{
36+
}
37+
38+
/// <summary>
39+
/// Initializes a new instance of the <see cref="CannotDereferenceException"/> class with a serialized data.
40+
/// </summary>
41+
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
42+
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
43+
protected CannotDereferenceException(SerializationInfo info, StreamingContext context)
44+
: base(info, context)
45+
{
46+
}
47+
}
48+
}

Diff for: LibGit2Sharp/Commit.cs

+10
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ internal Commit(Repository repo, ObjectId id)
5151
parents = new ParentsCollection(repo, id);
5252
}
5353

54+
/// <summary>
55+
/// This object is already a commit - no need to further dereference.
56+
/// </summary>
57+
/// <param name="throwsIfCanNotBeDereferencedToACommit"></param>
58+
/// <returns></returns>
59+
internal override Commit DereferenceToCommit(bool throwsIfCanNotBeDereferencedToACommit)
60+
{
61+
return this;
62+
}
63+
5464
/// <summary>
5565
/// Gets the <see cref="TreeEntry"/> pointed at by the <paramref name="relativePath"/> in the <see cref="Tree"/>.
5666
/// </summary>

Diff for: LibGit2Sharp/Core/Ensure.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ private static readonly Dictionary<GitErrorCode, Func<string, GitErrorCode, GitE
100100
{ GitErrorCode.NonFastForward, (m, r, c) => new NonFastForwardException(m, r, c) },
101101
{ GitErrorCode.MergeConflict, (m, r, c) => new MergeConflictException(m, r, c) },
102102
{ GitErrorCode.LockedFile, (m, r, c) => new LockedFileException(m, r, c) },
103+
{ GitErrorCode.NotFound, (m, r, c) => new NotFoundException(m, r, c) },
104+
{ GitErrorCode.Ambiguous, (m, r, c) => new AmbiguousSpecificationException(m, r, c) },
103105
};
104106

105107
private static void HandleError(int result)
@@ -218,7 +220,7 @@ public static void GitObjectIsNotNull(GitObject gitObject, string identifier)
218220
}
219221
else
220222
{
221-
exceptionBuilder = m => new LibGit2SharpException(m);
223+
exceptionBuilder = m => new NotFoundException(m);
222224
}
223225

224226
GitObjectIsNotNull(gitObject, identifier, exceptionBuilder);

Diff for: LibGit2Sharp/GitLink.cs

+15
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@ public class GitLink : GitObject
1414
protected GitLink()
1515
{ }
1616

17+
/// <summary>
18+
/// A GitLink cannot be dereferenced to a commit - throws or returns null.
19+
/// </summary>
20+
/// <param name="throwsIfCanNotBeDereferencedToACommit"></param>
21+
/// <returns></returns>
22+
internal override Commit DereferenceToCommit(bool throwsIfCanNotBeDereferencedToACommit)
23+
{
24+
if (throwsIfCanNotBeDereferencedToACommit)
25+
{
26+
throw new CannotDereferenceException("Cannot dereference a git-link object to a commit.");
27+
}
28+
29+
return null;
30+
}
31+
1732
internal GitLink(Repository repo, ObjectId id)
1833
: base(repo, id)
1934
{

Diff for: LibGit2Sharp/GitObject.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ internal static GitObject BuildFrom(Repository repo, ObjectId id, GitObjectType
7777
}
7878
}
7979

80-
internal Commit DereferenceToCommit(bool throwsIfCanNotBeDereferencedToACommit)
80+
/// <summary>
81+
/// Dereference object to a commit.
82+
/// </summary>
83+
/// <param name="throwsIfCanNotBeDereferencedToACommit"></param>
84+
/// <returns></returns>
85+
internal virtual Commit DereferenceToCommit(bool throwsIfCanNotBeDereferencedToACommit)
8186
{
8287
using (GitObjectSafeHandle peeledHandle = Proxy.git_object_peel(repo.Handle, Id, GitObjectType.Commit, throwsIfCanNotBeDereferencedToACommit))
8388
{

Diff for: LibGit2Sharp/LibGit2Sharp.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
<Compile Include="BranchCollectionExtensions.cs" />
6969
<Compile Include="BranchTrackingDetails.cs" />
7070
<Compile Include="BranchUpdater.cs" />
71+
<Compile Include="CannotDereferenceException.cs" />
7172
<Compile Include="CheckoutCallbacks.cs" />
7273
<Compile Include="CheckoutFileConflictStrategy.cs" />
7374
<Compile Include="CheckoutModifiers.cs" />

Diff for: LibGit2Sharp/TagAnnotation.cs

+19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using LibGit2Sharp.Core;
2+
using LibGit2Sharp.Core.Handles;
23

34
namespace LibGit2Sharp
45
{
@@ -31,6 +32,24 @@ internal TagAnnotation(Repository repo, ObjectId id)
3132
lazyMessage = group.AddLazy(Proxy.git_tag_message);
3233
}
3334

35+
/// <summary>
36+
/// Dereference tag to a commit.
37+
/// </summary>
38+
/// <param name="throwsIfCanNotBeDereferencedToACommit"></param>
39+
/// <returns></returns>
40+
internal override Commit DereferenceToCommit(bool throwsIfCanNotBeDereferencedToACommit)
41+
{
42+
using (GitObjectSafeHandle peeledHandle = Proxy.git_object_peel(repo.Handle, Id, GitObjectType.Commit, throwsIfCanNotBeDereferencedToACommit))
43+
{
44+
if (peeledHandle == null)
45+
{
46+
return null;
47+
}
48+
49+
return (Commit)BuildFrom(repo, Proxy.git_object_id(peeledHandle), GitObjectType.Commit, null);
50+
}
51+
}
52+
3453
/// <summary>
3554
/// Gets the name of this tag.
3655
/// </summary>

Diff for: LibGit2Sharp/Tree.cs

+15
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ internal Tree(Repository repo, ObjectId id, FilePath path)
3232
lazyCount = GitObjectLazyGroup.Singleton(repo, id, Proxy.git_tree_entrycount);
3333
}
3434

35+
/// <summary>
36+
/// A tree cannot be dereferenced to a commit - throws or returns null.
37+
/// </summary>
38+
/// <param name="throwsIfCanNotBeDereferencedToACommit"></param>
39+
/// <returns></returns>
40+
internal override Commit DereferenceToCommit(bool throwsIfCanNotBeDereferencedToACommit)
41+
{
42+
if (throwsIfCanNotBeDereferencedToACommit)
43+
{
44+
throw new CannotDereferenceException("Cannot dereference a tree object to a commit.");
45+
}
46+
47+
return null;
48+
}
49+
3550
/// <summary>
3651
/// Gets the number of <see cref="TreeEntry"/> immediately under this <see cref="Tree"/>.
3752
/// </summary>

0 commit comments

Comments
 (0)