Fast implementation of Git in pure Go codeberg.org/lindenii/furgit
git go
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

object/fetch: Use proper errors

Runxi Yu 84aac13e 02efb65b

+61 -45
+3 -3
object/fetch/exact_blob.go
··· 1 1 package fetch 2 2 3 3 import ( 4 - "fmt" 5 - 4 + giterrors "codeberg.org/lindenii/furgit/errors" 6 5 "codeberg.org/lindenii/furgit/object/blob" 7 6 objectid "codeberg.org/lindenii/furgit/object/id" 8 7 "codeberg.org/lindenii/furgit/object/stored" 8 + objecttype "codeberg.org/lindenii/furgit/object/type" 9 9 ) 10 10 11 11 // ExactBlob reads, parses, and wraps the blob at id. ··· 19 19 20 20 blob, ok := parsed.(*blob.Blob) 21 21 if !ok { 22 - return nil, fmt.Errorf("object/fetch: expected blob object %s, got %v", id, parsed.ObjectType()) 22 + return nil, &giterrors.ObjectTypeError{OID: id, Got: parsed.ObjectType(), Want: objecttype.TypeBlob} 23 23 } 24 24 25 25 return stored.New(id, blob), nil
+1 -1
object/fetch/exact_blob_reader.go
··· 12 12 // 13 13 // Labels: Life-Parent, Close-Caller. 14 14 func (r *Fetcher) ExactBlobReader(id objectid.ObjectID) (io.ReadCloser, int64, error) { 15 - return r.exactReader(id, objecttype.TypeBlob, "blob") 15 + return r.exactReader(id, objecttype.TypeBlob) 16 16 }
+3 -3
object/fetch/exact_commit.go
··· 1 1 package fetch 2 2 3 3 import ( 4 - "fmt" 5 - 4 + giterrors "codeberg.org/lindenii/furgit/errors" 6 5 "codeberg.org/lindenii/furgit/object/commit" 7 6 objectid "codeberg.org/lindenii/furgit/object/id" 8 7 "codeberg.org/lindenii/furgit/object/stored" 8 + objecttype "codeberg.org/lindenii/furgit/object/type" 9 9 ) 10 10 11 11 // ExactCommit reads, parses, and wraps the commit at id. ··· 19 19 20 20 commit, ok := parsed.(*commit.Commit) 21 21 if !ok { 22 - return nil, fmt.Errorf("object/fetch: expected commit object %s, got %v", id, parsed.ObjectType()) 22 + return nil, &giterrors.ObjectTypeError{OID: id, Got: parsed.ObjectType(), Want: objecttype.TypeCommit} 23 23 } 24 24 25 25 return stored.New(id, commit), nil
+1 -1
object/fetch/exact_commit_reader.go
··· 14 14 // 15 15 // Labels: Life-Parent, Close-Caller. 16 16 func (r *Fetcher) ExactCommitReader(id objectid.ObjectID) (io.ReadCloser, int64, error) { 17 - return r.exactReader(id, objecttype.TypeCommit, "commit") 17 + return r.exactReader(id, objecttype.TypeCommit) 18 18 }
+4 -4
object/fetch/exact_reader.go
··· 1 1 package fetch 2 2 3 3 import ( 4 - "fmt" 5 4 "io" 6 5 6 + giterrors "codeberg.org/lindenii/furgit/errors" 7 7 objectid "codeberg.org/lindenii/furgit/object/id" 8 8 objecttype "codeberg.org/lindenii/furgit/object/type" 9 9 ) 10 10 11 11 // exactReader reads one object's content stream and verifies that its header 12 12 // type matches wantType. 13 - func (r *Fetcher) exactReader(id objectid.ObjectID, wantType objecttype.Type, wantName string) (io.ReadCloser, int64, error) { 13 + func (r *Fetcher) exactReader(id objectid.ObjectID, wantType objecttype.Type) (io.ReadCloser, int64, error) { 14 14 gotType, size, rc, err := r.store.ReadReaderContent(id) 15 15 if err != nil { 16 - return nil, 0, err 16 + return nil, 0, wrapObjectReadError(id, err) 17 17 } 18 18 19 19 if gotType != wantType { 20 20 _ = rc.Close() 21 21 22 - return nil, 0, fmt.Errorf("object/fetch: expected %s object %s, got %v", wantName, id, gotType) 22 + return nil, 0, &giterrors.ObjectTypeError{OID: id, Got: gotType, Want: wantType} 23 23 } 24 24 25 25 return rc, size, nil
+3 -3
object/fetch/exact_tag.go
··· 1 1 package fetch 2 2 3 3 import ( 4 - "fmt" 5 - 4 + giterrors "codeberg.org/lindenii/furgit/errors" 6 5 objectid "codeberg.org/lindenii/furgit/object/id" 7 6 "codeberg.org/lindenii/furgit/object/stored" 8 7 "codeberg.org/lindenii/furgit/object/tag" 8 + objecttype "codeberg.org/lindenii/furgit/object/type" 9 9 ) 10 10 11 11 // ExactTag reads, parses, and wraps the tag at id. ··· 19 19 20 20 tag, ok := parsed.(*tag.Tag) 21 21 if !ok { 22 - return nil, fmt.Errorf("object/fetch: expected tag object %s, got %v", id, parsed.ObjectType()) 22 + return nil, &giterrors.ObjectTypeError{OID: id, Got: parsed.ObjectType(), Want: objecttype.TypeTag} 23 23 } 24 24 25 25 return stored.New(id, tag), nil
+1 -1
object/fetch/exact_tag_reader.go
··· 14 14 // 15 15 // Labels: Life-Parent, Close-Caller. 16 16 func (r *Fetcher) ExactTagReader(id objectid.ObjectID) (io.ReadCloser, int64, error) { 17 - return r.exactReader(id, objecttype.TypeTag, "tag") 17 + return r.exactReader(id, objecttype.TypeTag) 18 18 }
+3 -3
object/fetch/exact_tree.go
··· 1 1 package fetch 2 2 3 3 import ( 4 - "fmt" 5 - 4 + giterrors "codeberg.org/lindenii/furgit/errors" 6 5 objectid "codeberg.org/lindenii/furgit/object/id" 7 6 "codeberg.org/lindenii/furgit/object/stored" 8 7 "codeberg.org/lindenii/furgit/object/tree" 8 + objecttype "codeberg.org/lindenii/furgit/object/type" 9 9 ) 10 10 11 11 // ExactTree reads, parses, and wraps the tree at id. ··· 19 19 20 20 tree, ok := parsed.(*tree.Tree) 21 21 if !ok { 22 - return nil, fmt.Errorf("object/fetch: expected tree object %s, got %v", id, parsed.ObjectType()) 22 + return nil, &giterrors.ObjectTypeError{OID: id, Got: parsed.ObjectType(), Want: objecttype.TypeTree} 23 23 } 24 24 25 25 return stored.New(id, tree), nil
+1 -1
object/fetch/exact_tree_reader.go
··· 14 14 // 15 15 // Labels: Life-Parent, Close-Caller. 16 16 func (r *Fetcher) ExactTreeReader(id objectid.ObjectID) (io.ReadCloser, int64, error) { 17 - return r.exactReader(id, objecttype.TypeTree, "tree") 17 + return r.exactReader(id, objecttype.TypeTree) 18 18 }
+19
object/fetch/object_errors.go
··· 1 + package fetch 2 + 3 + import ( 4 + stderrors "errors" 5 + 6 + giterrors "codeberg.org/lindenii/furgit/errors" 7 + objectid "codeberg.org/lindenii/furgit/object/id" 8 + objectstore "codeberg.org/lindenii/furgit/object/store" 9 + ) 10 + 11 + // wrapObjectReadError maps raw object-store lookup failures to fetcher-level 12 + // object lookup errors. 13 + func wrapObjectReadError(id objectid.ObjectID, err error) error { 14 + if stderrors.Is(err, objectstore.ErrObjectNotFound) { 15 + return &giterrors.ObjectMissingError{OID: id} 16 + } 17 + 18 + return err 19 + }
+1 -1
object/fetch/object_parse.go
··· 10 10 func (r *Fetcher) parseObject(id objectid.ObjectID) (object.Object, error) { 11 11 ty, content, err := r.store.ReadBytesContent(id) 12 12 if err != nil { 13 - return nil, err 13 + return nil, wrapObjectReadError(id, err) 14 14 } 15 15 16 16 parsed, err := object.ParseWithoutHeader(ty, content, id.Algorithm())
+3 -3
object/fetch/peel_to_blob.go
··· 1 1 package fetch 2 2 3 3 import ( 4 - "fmt" 5 - 4 + giterrors "codeberg.org/lindenii/furgit/errors" 6 5 "codeberg.org/lindenii/furgit/object/blob" 7 6 objectid "codeberg.org/lindenii/furgit/object/id" 8 7 "codeberg.org/lindenii/furgit/object/stored" 9 8 "codeberg.org/lindenii/furgit/object/tag" 9 + objecttype "codeberg.org/lindenii/furgit/object/type" 10 10 ) 11 11 12 12 // PeelToBlob peels tags until it reaches a blob. ··· 25 25 case *tag.Tag: 26 26 id = parsed.Target 27 27 default: 28 - return nil, fmt.Errorf("object/fetch: expected blob-ish object %s, got %v", id, parsed.ObjectType()) 28 + return nil, &giterrors.ObjectTypeError{OID: id, Got: parsed.ObjectType(), Want: objecttype.TypeBlob} 29 29 } 30 30 } 31 31 }
+4 -5
object/fetch/peel_to_blob_id.go
··· 1 1 package fetch 2 2 3 3 import ( 4 - "fmt" 5 - 4 + giterrors "codeberg.org/lindenii/furgit/errors" 6 5 objectid "codeberg.org/lindenii/furgit/object/id" 7 6 objecttype "codeberg.org/lindenii/furgit/object/type" 8 7 ) ··· 12 11 for { 13 12 ty, _, err := r.store.ReadHeader(id) 14 13 if err != nil { 15 - return objectid.ObjectID{}, err 14 + return objectid.ObjectID{}, wrapObjectReadError(id, err) 16 15 } 17 16 18 17 switch ty { ··· 31 30 objecttype.TypeFuture, 32 31 objecttype.TypeOfsDelta, 33 32 objecttype.TypeRefDelta: 34 - return objectid.ObjectID{}, fmt.Errorf("object/fetch: expected blob-ish object %s, got %v", id, ty) 33 + return objectid.ObjectID{}, &giterrors.ObjectTypeError{OID: id, Got: ty, Want: objecttype.TypeBlob} 35 34 default: 36 - return objectid.ObjectID{}, fmt.Errorf("object/fetch: expected blob-ish object %s, got %v", id, ty) 35 + return objectid.ObjectID{}, &giterrors.ObjectTypeError{OID: id, Got: ty, Want: objecttype.TypeBlob} 37 36 } 38 37 } 39 38 }
+3 -3
object/fetch/peel_to_commit.go
··· 1 1 package fetch 2 2 3 3 import ( 4 - "fmt" 5 - 4 + giterrors "codeberg.org/lindenii/furgit/errors" 6 5 "codeberg.org/lindenii/furgit/object/commit" 7 6 objectid "codeberg.org/lindenii/furgit/object/id" 8 7 "codeberg.org/lindenii/furgit/object/stored" 9 8 "codeberg.org/lindenii/furgit/object/tag" 9 + objecttype "codeberg.org/lindenii/furgit/object/type" 10 10 ) 11 11 12 12 // PeelToCommit peels tags until it reaches a commit. ··· 25 25 case *tag.Tag: 26 26 id = parsed.Target 27 27 default: 28 - return nil, fmt.Errorf("object/fetch: expected commit-ish object %s, got %v", id, parsed.ObjectType()) 28 + return nil, &giterrors.ObjectTypeError{OID: id, Got: parsed.ObjectType(), Want: objecttype.TypeCommit} 29 29 } 30 30 } 31 31 }
+4 -5
object/fetch/peel_to_commit_id.go
··· 1 1 package fetch 2 2 3 3 import ( 4 - "fmt" 5 - 4 + giterrors "codeberg.org/lindenii/furgit/errors" 6 5 objectid "codeberg.org/lindenii/furgit/object/id" 7 6 objecttype "codeberg.org/lindenii/furgit/object/type" 8 7 ) ··· 12 11 for { 13 12 ty, _, err := r.store.ReadHeader(id) 14 13 if err != nil { 15 - return objectid.ObjectID{}, err 14 + return objectid.ObjectID{}, wrapObjectReadError(id, err) 16 15 } 17 16 18 17 switch ty { ··· 31 30 objecttype.TypeFuture, 32 31 objecttype.TypeOfsDelta, 33 32 objecttype.TypeRefDelta: 34 - return objectid.ObjectID{}, fmt.Errorf("object/fetch: expected commit-ish object %s, got %v", id, ty) 33 + return objectid.ObjectID{}, &giterrors.ObjectTypeError{OID: id, Got: ty, Want: objecttype.TypeCommit} 35 34 default: 36 - return objectid.ObjectID{}, fmt.Errorf("object/fetch: expected commit-ish object %s, got %v", id, ty) 35 + return objectid.ObjectID{}, &giterrors.ObjectTypeError{OID: id, Got: ty, Want: objecttype.TypeCommit} 37 36 } 38 37 } 39 38 }
+3 -3
object/fetch/peel_to_tree.go
··· 1 1 package fetch 2 2 3 3 import ( 4 - "fmt" 5 - 4 + giterrors "codeberg.org/lindenii/furgit/errors" 6 5 "codeberg.org/lindenii/furgit/object/commit" 7 6 objectid "codeberg.org/lindenii/furgit/object/id" 8 7 "codeberg.org/lindenii/furgit/object/stored" 9 8 "codeberg.org/lindenii/furgit/object/tag" 10 9 "codeberg.org/lindenii/furgit/object/tree" 10 + objecttype "codeberg.org/lindenii/furgit/object/type" 11 11 ) 12 12 13 13 // PeelToTree peels tags until it reaches a tree or commit. If it reaches a ··· 29 29 case *tag.Tag: 30 30 id = parsed.Target 31 31 default: 32 - return nil, fmt.Errorf("object/fetch: expected tree-ish object %s, got %v", id, parsed.ObjectType()) 32 + return nil, &giterrors.ObjectTypeError{OID: id, Got: parsed.ObjectType(), Want: objecttype.TypeTree} 33 33 } 34 34 } 35 35 }
+4 -5
object/fetch/peel_to_tree_id.go
··· 1 1 package fetch 2 2 3 3 import ( 4 - "fmt" 5 - 4 + giterrors "codeberg.org/lindenii/furgit/errors" 6 5 objectid "codeberg.org/lindenii/furgit/object/id" 7 6 objecttype "codeberg.org/lindenii/furgit/object/type" 8 7 ) ··· 13 12 for { 14 13 ty, _, err := r.store.ReadHeader(id) 15 14 if err != nil { 16 - return objectid.ObjectID{}, err 15 + return objectid.ObjectID{}, wrapObjectReadError(id, err) 17 16 } 18 17 19 18 switch ty { ··· 38 37 objecttype.TypeFuture, 39 38 objecttype.TypeOfsDelta, 40 39 objecttype.TypeRefDelta: 41 - return objectid.ObjectID{}, fmt.Errorf("object/fetch: expected tree-ish object %s, got %v", id, ty) 40 + return objectid.ObjectID{}, &giterrors.ObjectTypeError{OID: id, Got: ty, Want: objecttype.TypeTree} 42 41 default: 43 - return objectid.ObjectID{}, fmt.Errorf("object/fetch: expected tree-ish object %s, got %v", id, ty) 42 + return objectid.ObjectID{}, &giterrors.ObjectTypeError{OID: id, Got: ty, Want: objecttype.TypeTree} 44 43 } 45 44 } 46 45 }