Skip to content

Commit

Permalink
Merge pull request ipfs/go-path#28 from ipfs/feat/better-errors
Browse files Browse the repository at this point in the history
include the path in path errors

This commit was moved from ipfs/go-path@cf63222
  • Loading branch information
Stebalien authored May 17, 2019
2 parents 912c1a0 + 218696c commit dc85526
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 23 deletions.
23 changes: 23 additions & 0 deletions path/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package path

import (
"fmt"
)

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

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

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

func (e *pathError) Path() string {
return e.path
}
32 changes: 11 additions & 21 deletions path/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/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 dc85526

Please sign in to comment.