mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
feat: add blockstore: block not found matching too
This commit was moved from ipfs/go-ipfs-http-client@a3354f062c
This commit is contained in:
parent
ddd36645b2
commit
775bcb7f09
@ -66,7 +66,7 @@ func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Error != nil {
|
||||
return nil, parseIPLDNotFoundWithFallbackToError(resp.Error)
|
||||
return nil, parseErrNotFoundWithFallbackToError(resp.Error)
|
||||
}
|
||||
|
||||
//TODO: make get return ReadCloser to avoid copying
|
||||
@ -98,14 +98,14 @@ func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRm
|
||||
return err
|
||||
}
|
||||
|
||||
return parseIPLDNotFoundWithFallbackToMSG(removedBlock.Error)
|
||||
return parseErrNotFoundWithFallbackToMSG(removedBlock.Error)
|
||||
}
|
||||
|
||||
func (api *BlockAPI) Stat(ctx context.Context, p path.Path) (iface.BlockStat, error) {
|
||||
var out blockStat
|
||||
err := api.core().Request("block/stat", p.String()).Exec(ctx, &out)
|
||||
if err != nil {
|
||||
return nil, parseIPLDNotFoundWithFallbackToError(err)
|
||||
return nil, parseErrNotFoundWithFallbackToError(err)
|
||||
}
|
||||
out.cid, err = cid.Parse(out.Key)
|
||||
if err != nil {
|
||||
|
||||
@ -8,6 +8,8 @@ import (
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
)
|
||||
|
||||
// This file handle parsing and returning the correct ABI based errors from error messages
|
||||
|
||||
type prePostWrappedNotFoundError struct {
|
||||
pre string
|
||||
post string
|
||||
@ -27,8 +29,8 @@ func (e prePostWrappedNotFoundError) Unwrap() error {
|
||||
return e.wrapped
|
||||
}
|
||||
|
||||
func parseIPLDNotFoundWithFallbackToMSG(msg string) error {
|
||||
err, handled := parseIPLDNotFound(msg)
|
||||
func parseErrNotFoundWithFallbackToMSG(msg string) error {
|
||||
err, handled := parseErrNotFound(msg)
|
||||
if handled {
|
||||
return err
|
||||
}
|
||||
@ -36,8 +38,8 @@ func parseIPLDNotFoundWithFallbackToMSG(msg string) error {
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
func parseIPLDNotFoundWithFallbackToError(msg error) error {
|
||||
err, handled := parseIPLDNotFound(msg.Error())
|
||||
func parseErrNotFoundWithFallbackToError(msg error) error {
|
||||
err, handled := parseErrNotFound(msg.Error())
|
||||
if handled {
|
||||
return err
|
||||
}
|
||||
@ -57,13 +59,25 @@ func notAsciiLetterOrDigits(r rune) bool {
|
||||
return notAsciiLetterOrDigitsLUT[r] > 0
|
||||
}
|
||||
|
||||
// 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 parseIPLDNotFound(msg string) (error, bool) {
|
||||
func parseErrNotFound(msg string) (error, bool) {
|
||||
if msg == "" {
|
||||
return nil, true // Fast path
|
||||
}
|
||||
|
||||
if err, handled := parseIPLDErrNotFound(msg); handled {
|
||||
return err, true
|
||||
}
|
||||
|
||||
if err, handled := parseBlockstoreNotFound(msg); handled {
|
||||
return err, true
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
//lint:ignore ST1008 using error as values
|
||||
func parseIPLDErrNotFound(msg string) (error, bool) {
|
||||
// The patern we search for is:
|
||||
const ipldErrNotFoundKey = "ipld: could not find " /*CID*/
|
||||
// We try to parse the CID, if it's invalid we give up and return a simple text error.
|
||||
@ -114,3 +128,33 @@ func parseIPLDNotFound(msg string) (error, bool) {
|
||||
|
||||
return err, true
|
||||
}
|
||||
|
||||
// This is a simple error type that just return msg as Error().
|
||||
// But that also match ipld.ErrNotFound when called with Is(err).
|
||||
// That is needed to keep compatiblity with code that use string.Contains(err.Error(), "blockstore: block not found")
|
||||
// and code using ipld.ErrNotFound
|
||||
type blockstoreNotFoundMatchingIPLDErrNotFound struct {
|
||||
msg string
|
||||
}
|
||||
|
||||
func (e blockstoreNotFoundMatchingIPLDErrNotFound) String() string {
|
||||
return e.Error()
|
||||
}
|
||||
|
||||
func (e blockstoreNotFoundMatchingIPLDErrNotFound) Error() string {
|
||||
return e.msg
|
||||
}
|
||||
|
||||
func (e blockstoreNotFoundMatchingIPLDErrNotFound) Is(err error) bool {
|
||||
_, ok := err.(ipld.ErrNotFound)
|
||||
return ok
|
||||
}
|
||||
|
||||
//lint:ignore ST1008 using error as values
|
||||
func parseBlockstoreNotFound(msg string) (error, bool) {
|
||||
if !strings.Contains(msg, "blockstore: block not found") {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return blockstoreNotFoundMatchingIPLDErrNotFound{msg: msg}, true
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ var randomSha256MH = mh.Multihash{0x12, 0x20, 0x88, 0x82, 0x73, 0x37, 0x7c, 0xc1
|
||||
func doParseIpldNotFoundTest(t *testing.T, original error) {
|
||||
originalMsg := original.Error()
|
||||
|
||||
rebuilt := parseIPLDNotFoundWithFallbackToMSG(originalMsg)
|
||||
rebuilt := parseErrNotFoundWithFallbackToMSG(originalMsg)
|
||||
|
||||
rebuiltMsg := rebuilt.Error()
|
||||
|
||||
@ -32,7 +32,7 @@ func doParseIpldNotFoundTest(t *testing.T, original error) {
|
||||
}
|
||||
|
||||
func TestParseIPLDNotFound(t *testing.T) {
|
||||
if err := parseIPLDNotFoundWithFallbackToMSG(""); err != nil {
|
||||
if err := parseErrNotFoundWithFallbackToMSG(""); err != nil {
|
||||
t.Errorf("expected empty string to give no error; got %T %q", err, err.Error())
|
||||
}
|
||||
|
||||
@ -59,6 +59,27 @@ func TestParseIPLDNotFound(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlockstoreNotFoundMatchingIPLDErrNotFound(t *testing.T) {
|
||||
if !ipld.IsNotFound(blockstoreNotFoundMatchingIPLDErrNotFound{}) {
|
||||
t.Fatalf("expected blockstoreNotFoundMatchingIPLDErrNotFound to match ipld.IsNotFound; got false")
|
||||
}
|
||||
|
||||
for _, wrap := range [...]string{
|
||||
"",
|
||||
"merkledag: %w",
|
||||
"testing: %w the test",
|
||||
"%w is wrong",
|
||||
} {
|
||||
var err error = blockstoreNotFoundMatchingIPLDErrNotFound{"blockstore: block not found"}
|
||||
|
||||
if wrap != "" {
|
||||
err = fmt.Errorf(wrap, err)
|
||||
}
|
||||
|
||||
doParseIpldNotFoundTest(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotAsciiLetterOrDigits(t *testing.T) {
|
||||
for i := rune(0); i <= 256; i++ {
|
||||
if notAsciiLetterOrDigits(i) != !strings.ContainsAny(string(i), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user