Skip to content

Commit

Permalink
feat: expose ErrInvalidPath and implement .Is function (#66)
Browse files Browse the repository at this point in the history


This commit was moved from ipfs/go-path@6793198
  • Loading branch information
hacdias authored Feb 23, 2023
1 parent 5cfe8e6 commit cd0d3b1
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 16 deletions.
16 changes: 10 additions & 6 deletions path/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ import (
"fmt"
)

// helper type so path parsing errors include the path
type pathError struct {
type ErrInvalidPath struct {
error error
path string
}

func (e *pathError) Error() string {
func (e ErrInvalidPath) Error() string {
return fmt.Sprintf("invalid path %q: %s", e.path, e.error)
}

func (e *pathError) Unwrap() error {
func (e ErrInvalidPath) Unwrap() error {
return e.error
}

func (e *pathError) Path() string {
return e.path
func (e ErrInvalidPath) Is(err error) bool {
switch err.(type) {
case ErrInvalidPath:
return true
default:
return false
}
}
16 changes: 16 additions & 0 deletions path/error_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package path

import (
"errors"
"testing"
)

func TestErrorIs(t *testing.T) {
if !errors.Is(ErrInvalidPath{path: "foo", error: errors.New("bar")}, ErrInvalidPath{}) {
t.Fatal("error must be error")
}

if !errors.Is(&ErrInvalidPath{path: "foo", error: errors.New("bar")}, ErrInvalidPath{}) {
t.Fatal("pointer to error must be error")
}
}
20 changes: 10 additions & 10 deletions path/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,33 +97,33 @@ func ParsePath(txt string) (Path, error) {
// we expect this to start with a hash, and be an 'ipfs' path
if parts[0] != "" {
if _, err := decodeCid(parts[0]); err != nil {
return "", &pathError{error: err, path: txt}
return "", &ErrInvalidPath{error: err, path: txt}
}
// The case when the path starts with hash without a protocol prefix
return Path("/ipfs/" + txt), nil
}

if len(parts) < 3 {
return "", &pathError{error: fmt.Errorf("invalid ipfs path"), path: txt}
return "", &ErrInvalidPath{error: fmt.Errorf("invalid ipfs path"), path: txt}
}

//TODO: make this smarter
switch parts[1] {
case "ipfs", "ipld":
if parts[2] == "" {
return "", &pathError{error: fmt.Errorf("not enough path components"), path: txt}
return "", &ErrInvalidPath{error: fmt.Errorf("not enough path components"), path: txt}
}
// Validate Cid.
_, err := decodeCid(parts[2])
if err != nil {
return "", &pathError{error: fmt.Errorf("invalid CID: %s", err), path: txt}
return "", &ErrInvalidPath{error: fmt.Errorf("invalid CID: %w", err), path: txt}
}
case "ipns":
if parts[2] == "" {
return "", &pathError{error: fmt.Errorf("not enough path components"), path: txt}
return "", &ErrInvalidPath{error: fmt.Errorf("not enough path components"), path: txt}
}
default:
return "", &pathError{error: fmt.Errorf("unknown namespace %q", parts[1]), path: txt}
return "", &ErrInvalidPath{error: fmt.Errorf("unknown namespace %q", parts[1]), path: txt}
}

return Path(txt), nil
Expand All @@ -132,12 +132,12 @@ func ParsePath(txt string) (Path, error) {
// ParseCidToPath takes a CID in string form and returns a valid ipfs Path.
func ParseCidToPath(txt string) (Path, error) {
if txt == "" {
return "", &pathError{error: fmt.Errorf("empty"), path: txt}
return "", &ErrInvalidPath{error: fmt.Errorf("empty"), path: txt}
}

c, err := decodeCid(txt)
if err != nil {
return "", &pathError{error: err, path: txt}
return "", &ErrInvalidPath{error: err, path: txt}
}

return FromCid(c), nil
Expand Down Expand Up @@ -169,13 +169,13 @@ func SplitAbsPath(fpath Path) (cid.Cid, []string, error) {

// if nothing, bail.
if len(parts) == 0 {
return cid.Cid{}, nil, &pathError{error: fmt.Errorf("empty"), path: string(fpath)}
return cid.Cid{}, nil, &ErrInvalidPath{error: fmt.Errorf("empty"), path: string(fpath)}
}

c, err := decodeCid(parts[0])
// first element in the path is a cid
if err != nil {
return cid.Cid{}, nil, &pathError{error: fmt.Errorf("invalid CID: %s", err), path: string(fpath)}
return cid.Cid{}, nil, &ErrInvalidPath{error: fmt.Errorf("invalid CID: %w", err), path: string(fpath)}
}

return c, parts[1:], nil
Expand Down

0 comments on commit cd0d3b1

Please sign in to comment.