Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

Commit

Permalink
include the path in path errors
Browse files Browse the repository at this point in the history
This should improve UX by telling the user the path we failed to parse.
  • Loading branch information
Stebalien committed May 17, 2019
1 parent a1e7a84 commit 30d92a0
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 23 deletions.
32 changes: 11 additions & 21 deletions path.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,13 @@
package path

import (
"errors"
"fmt"
"path"
"strings"

cid "github.com/ipfs/go-cid"
)

var (
// ErrBadPath is returned when a given path is incorrectly formatted
ErrBadPath = errors.New("invalid 'ipfs ref' path")

// ErrNoComponents is used when Paths after a protocol
// do not contain at least one component
ErrNoComponents = errors.New(
"path must contain at least one component")
)

// A Path represents an ipfs content path:
// * /<cid>/path/to/file
// * /ipfs/<cid>
Expand Down Expand Up @@ -107,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 := cid.Decode(parts[0]); err != nil {
return "", ErrBadPath
return "", &pathError{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 "", ErrBadPath
return "", &pathError{error: fmt.Errorf("path does not begin with '/'"), path: txt}
}

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

return Path(txt), nil
Expand All @@ -142,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 "", ErrNoComponents
return "", &pathError{error: fmt.Errorf("empty"), path: txt}
}

c, err := cid.Decode(txt)
if err != nil {
return "", err
return "", &pathError{error: err, path: txt}
}

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

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

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

return c, parts[1:], nil
Expand Down
5 changes: 3 additions & 2 deletions path_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package path

import (
"strings"
"testing"
)

Expand Down Expand Up @@ -44,8 +45,8 @@ func TestNoComponents(t *testing.T) {
"/ipld/",
} {
_, err := ParsePath(s)
if err != ErrNoComponents {
t.Errorf("expected ErrNoComponents, got %s", err)
if err == nil || !strings.Contains(err.Error(), "not enough path components") || !strings.Contains(err.Error(), s) {
t.Error("wrong error")
}
}
}
Expand Down

0 comments on commit 30d92a0

Please sign in to comment.