@cryptotaxi247 / kubo / commits / 775bcb7f0

feat: add blockstore: block not found matching too

This commit was moved from ipfs/go-ipfs-http-client@a3354f062c97bcb6412e74ecfb24e84208edc479

Jorropo committed Apr 1, 2022 at 00:23 UTC 775bcb7f09de0d13a64b013ccaefa253e44c3403
3 files changed +76 -11
client/httpapi/block.go
+3 -3
@@ -66,7 +66,7 @@ func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) {
66 return nil, err
67 }
68 if resp.Error != nil {
69 - return nil, parseIPLDNotFoundWithFallbackToError(resp.Error)
69 + return nil, parseErrNotFoundWithFallbackToError(resp.Error)
70 }
71
72 //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
98 return err
99 }
100
101 - return parseIPLDNotFoundWithFallbackToMSG(removedBlock.Error)
101 + return parseErrNotFoundWithFallbackToMSG(removedBlock.Error)
102 }
103
104 func (api *BlockAPI) Stat(ctx context.Context, p path.Path) (iface.BlockStat, error) {
105 var out blockStat
106 err := api.core().Request("block/stat", p.String()).Exec(ctx, &out)
107 if err != nil {
108 - return nil, parseIPLDNotFoundWithFallbackToError(err)
108 + return nil, parseErrNotFoundWithFallbackToError(err)
109 }
110 out.cid, err = cid.Parse(out.Key)
111 if err != nil {
client/httpapi/errors.go
+50 -6
@@ -8,6 +8,8 @@ import (
8 ipld "github.com/ipfs/go-ipld-format"
9 )
10
11 +// This file handle parsing and returning the correct ABI based errors from error messages
12 +
13 type prePostWrappedNotFoundError struct {
14 pre string
15 post string
@@ -27,8 +29,8 @@ func (e prePostWrappedNotFoundError) Unwrap() error {
29 return e.wrapped
30 }
31
30 -func parseIPLDNotFoundWithFallbackToMSG(msg string) error {
31 - err, handled := parseIPLDNotFound(msg)
32 +func parseErrNotFoundWithFallbackToMSG(msg string) error {
33 + err, handled := parseErrNotFound(msg)
34 if handled {
35 return err
36 }
@@ -36,8 +38,8 @@ func parseIPLDNotFoundWithFallbackToMSG(msg string) error {
38 return errors.New(msg)
39 }
40
39 -func parseIPLDNotFoundWithFallbackToError(msg error) error {
40 - err, handled := parseIPLDNotFound(msg.Error())
41 +func parseErrNotFoundWithFallbackToError(msg error) error {
42 + err, handled := parseErrNotFound(msg.Error())
43 if handled {
44 return err
45 }
@@ -57,13 +59,25 @@ func notAsciiLetterOrDigits(r rune) bool {
59 return notAsciiLetterOrDigitsLUT[r] > 0
60 }
61
60 -// This file handle parsing and returning the correct ABI based errors from error messages
62 //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
62 -func parseIPLDNotFound(msg string) (error, bool) {
63 +func parseErrNotFound(msg string) (error, bool) {
64 if msg == "" {
65 return nil, true // Fast path
66 }
67
68 + if err, handled := parseIPLDErrNotFound(msg); handled {
69 + return err, true
70 + }
71 +
72 + if err, handled := parseBlockstoreNotFound(msg); handled {
73 + return err, true
74 + }
75 +
76 + return nil, false
77 +}
78 +
79 +//lint:ignore ST1008 using error as values
80 +func parseIPLDErrNotFound(msg string) (error, bool) {
81 // The patern we search for is:
82 const ipldErrNotFoundKey = "ipld: could not find " /*CID*/
83 // 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) {
128
129 return err, true
130 }
131 +
132 +// This is a simple error type that just return msg as Error().
133 +// But that also match ipld.ErrNotFound when called with Is(err).
134 +// That is needed to keep compatiblity with code that use string.Contains(err.Error(), "blockstore: block not found")
135 +// and code using ipld.ErrNotFound
136 +type blockstoreNotFoundMatchingIPLDErrNotFound struct {
137 + msg string
138 +}
139 +
140 +func (e blockstoreNotFoundMatchingIPLDErrNotFound) String() string {
141 + return e.Error()
142 +}
143 +
144 +func (e blockstoreNotFoundMatchingIPLDErrNotFound) Error() string {
145 + return e.msg
146 +}
147 +
148 +func (e blockstoreNotFoundMatchingIPLDErrNotFound) Is(err error) bool {
149 + _, ok := err.(ipld.ErrNotFound)
150 + return ok
151 +}
152 +
153 +//lint:ignore ST1008 using error as values
154 +func parseBlockstoreNotFound(msg string) (error, bool) {
155 + if !strings.Contains(msg, "blockstore: block not found") {
156 + return nil, false
157 + }
158 +
159 + return blockstoreNotFoundMatchingIPLDErrNotFound{msg: msg}, true
160 +}
client/httpapi/errors_test.go
+23 -2
@@ -16,7 +16,7 @@ var randomSha256MH = mh.Multihash{0x12, 0x20, 0x88, 0x82, 0x73, 0x37, 0x7c, 0xc1
16 func doParseIpldNotFoundTest(t *testing.T, original error) {
17 originalMsg := original.Error()
18
19 - rebuilt := parseIPLDNotFoundWithFallbackToMSG(originalMsg)
19 + rebuilt := parseErrNotFoundWithFallbackToMSG(originalMsg)
20
21 rebuiltMsg := rebuilt.Error()
22
@@ -32,7 +32,7 @@ func doParseIpldNotFoundTest(t *testing.T, original error) {
32 }
33
34 func TestParseIPLDNotFound(t *testing.T) {
35 - if err := parseIPLDNotFoundWithFallbackToMSG(""); err != nil {
35 + if err := parseErrNotFoundWithFallbackToMSG(""); err != nil {
36 t.Errorf("expected empty string to give no error; got %T %q", err, err.Error())
37 }
38
@@ -59,6 +59,27 @@ func TestParseIPLDNotFound(t *testing.T) {
59 }
60 }
61
62 +func TestBlockstoreNotFoundMatchingIPLDErrNotFound(t *testing.T) {
63 + if !ipld.IsNotFound(blockstoreNotFoundMatchingIPLDErrNotFound{}) {
64 + t.Fatalf("expected blockstoreNotFoundMatchingIPLDErrNotFound to match ipld.IsNotFound; got false")
65 + }
66 +
67 + for _, wrap := range [...]string{
68 + "",
69 + "merkledag: %w",
70 + "testing: %w the test",
71 + "%w is wrong",
72 + } {
73 + var err error = blockstoreNotFoundMatchingIPLDErrNotFound{"blockstore: block not found"}
74 +
75 + if wrap != "" {
76 + err = fmt.Errorf(wrap, err)
77 + }
78 +
79 + doParseIpldNotFoundTest(t, err)
80 + }
81 +}
82 +
83 func TestNotAsciiLetterOrDigits(t *testing.T) {
84 for i := rune(0); i <= 256; i++ {
85 if notAsciiLetterOrDigits(i) != !strings.ContainsAny(string(i), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") {