This repository has been archived by the owner on Oct 5, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: make Block().* return correct ABI based ipld.ErrNotFound errors
- Loading branch information
Showing
5 changed files
with
418 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package httpapi | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
|
||
"github.com/ipfs/go-cid" | ||
ipld "github.com/ipfs/go-ipld-format" | ||
) | ||
|
||
type prePostWrappedNotFoundError struct { | ||
pre string | ||
post string | ||
|
||
wrapped ipld.ErrNotFound | ||
} | ||
|
||
func (e prePostWrappedNotFoundError) String() string { | ||
return e.Error() | ||
} | ||
|
||
func (e prePostWrappedNotFoundError) Error() string { | ||
return e.pre + e.wrapped.Error() + e.post | ||
} | ||
|
||
func (e prePostWrappedNotFoundError) Unwrap() error { | ||
return e.wrapped | ||
} | ||
|
||
func abyfyIpldNotFoundFallbackToMSG(msg string) error { | ||
err, handled := abyfyIpldNotFound(msg) | ||
if handled { | ||
return err | ||
} | ||
|
||
return errors.New(msg) | ||
} | ||
|
||
func abyfyIpldNotFoundFallbackToError(msg error) error { | ||
err, handled := abyfyIpldNotFound(msg.Error()) | ||
if handled { | ||
return err | ||
} | ||
|
||
return err | ||
} | ||
|
||
// This file handle parsing and returning the correct ABI based errors from error messages | ||
//lint: ignore ST1008 this function is not using the error as a mean to return failure but it massages it to return the correct type | ||
func abyfyIpldNotFound(msg string) (error, bool) { | ||
if msg == "" { | ||
return nil, true // Fast path | ||
} | ||
|
||
// The patern we search for is: | ||
// node not found (fallback) | ||
// or | ||
// CID not found (here we parse the CID) | ||
notFoundIndex := strings.LastIndex(msg, " not found") | ||
|
||
if notFoundIndex == -1 { | ||
// Unknown, ot found not found | ||
return nil, false | ||
} | ||
|
||
preNotFound := msg[:notFoundIndex] | ||
|
||
var c cid.Cid | ||
var preIndex int | ||
if strings.HasSuffix(preNotFound, "node") { | ||
// Fallback case | ||
c = cid.Undef | ||
preIndex = notFoundIndex - len("node") | ||
} else { | ||
// Assume that CIDs does not include whitespace to pull out the CID | ||
preIndex = strings.LastIndexByte(preNotFound, ' ') | ||
// + 1 is to normalise not founds to zeros and point to the start of the CID, not the previous space | ||
preIndex++ | ||
var err error | ||
c, err = cid.Decode(preNotFound[preIndex:]) | ||
if err != nil { | ||
// Unknown | ||
return nil, false | ||
} | ||
} | ||
|
||
postIndex := notFoundIndex + len(" not found") | ||
|
||
err := ipld.ErrNotFound{Cid: c} | ||
|
||
pre := msg[:preIndex] | ||
post := msg[postIndex:] | ||
|
||
if len(pre) > 0 || len(post) > 0 { | ||
// We have some text to wrap arround the ErrNotFound one | ||
return prePostWrappedNotFoundError{ | ||
pre: pre, | ||
post: post, | ||
wrapped: err, | ||
}, true | ||
} | ||
|
||
return err, true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package httpapi | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/ipfs/go-cid" | ||
ipld "github.com/ipfs/go-ipld-format" | ||
mh "github.com/multiformats/go-multihash" | ||
) | ||
|
||
var randomSha256MH = mh.Multihash{0x12, 0x20, 0x88, 0x82, 0x73, 0x37, 0x7c, 0xc1, 0xc9, 0x96, 0xad, 0xee, 0xd, 0x26, 0x84, 0x2, 0xc9, 0xc9, 0x5c, 0xf9, 0x5c, 0x4d, 0x9b, 0xc3, 0x3f, 0xfb, 0x4a, 0xd8, 0xaf, 0x28, 0x6b, 0xca, 0x1a, 0xf2} | ||
|
||
func doAbyfyIpldNotFoundTest(t *testing.T, original error) { | ||
originalMsg := original.Error() | ||
|
||
rebuilt := abyfyIpldNotFoundFallbackToMSG(originalMsg) | ||
|
||
rebuiltMsg := rebuilt.Error() | ||
|
||
if originalMsg != rebuiltMsg { | ||
t.Errorf("expected message to be %q; got %q", originalMsg, rebuiltMsg) | ||
} | ||
|
||
originalNotFound := ipld.IsNotFound(original) | ||
rebuiltNotFound := ipld.IsNotFound(original) | ||
if originalNotFound != rebuiltNotFound { | ||
t.Errorf("expected Ipld.IsNotFound to be %t; got %t", originalNotFound, rebuiltNotFound) | ||
} | ||
} | ||
|
||
func TestAbyfyIpldNotFound(t *testing.T) { | ||
if err := abyfyIpldNotFoundFallbackToMSG(""); err != nil { | ||
t.Errorf("expected empty string to give no error; got %T %q", err, err.Error()) | ||
} | ||
|
||
for _, wrap := range [...]string{ | ||
"", | ||
"merkledag: %w", | ||
"testing: %w the test", | ||
"%w is wrong", | ||
} { | ||
for _, err := range [...]error{ | ||
errors.New("file not found"), | ||
errors.New(" not found"), | ||
errors.New("Bad_CID not found"), | ||
errors.New("network connection timeout"), | ||
ipld.ErrNotFound{Cid: cid.Undef}, | ||
ipld.ErrNotFound{Cid: cid.NewCidV0(randomSha256MH)}, | ||
ipld.ErrNotFound{Cid: cid.NewCidV1(cid.Raw, randomSha256MH)}, | ||
} { | ||
if wrap != "" { | ||
err = fmt.Errorf(wrap, err) | ||
} | ||
|
||
doAbyfyIpldNotFoundTest(t, err) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.