@cryptotaxi247 / kubo / commits / f72110c2d

fix: use error instead of strings as error in blockstoreutil/remove

Jorropo committed Apr 1, 2022 at 01:18 UTC f72110c2d8676ec770722aad44547d6169216eec
3 files changed +46 -22
blocks/blockstoreutil/remove.go
+14 -13
@@ -3,6 +3,7 @@ package blockstoreutil
3
4 import (
5 "context"
6 + "errors"
7 "fmt"
8 "io"
9
@@ -13,14 +14,14 @@ import (
14 )
15
16 // RemovedBlock is used to represent the result of removing a block.
16 -// If a block was removed successfully, then the Error string will be
17 -// empty. If a block could not be removed, then Error will contain the
17 +// If a block was removed successfully, then the Error will be empty.
18 +// If a block could not be removed, then Error will contain the
19 // reason the block could not be removed. If the removal was aborted
20 // due to a fatal error, Hash will be empty, Error will contain the
21 // reason, and no more results will be sent.
22 type RemovedBlock struct {
22 - Hash string `json:",omitempty"`
23 - Error string `json:",omitempty"`
23 + Hash string
24 + Error error
25 }
26
27 // RmBlocksOpts is used to wrap options for RmBlocks().
@@ -51,17 +52,17 @@ func RmBlocks(ctx context.Context, blocks bs.GCBlockstore, pins pin.Pinner, cids
52 // remove this sometime in the future.
53 has, err := blocks.Has(ctx, c)
54 if err != nil {
54 - out <- &RemovedBlock{Hash: c.String(), Error: err.Error()}
55 + out <- &RemovedBlock{Hash: c.String(), Error: err}
56 continue
57 }
58 if !has && !opts.Force {
58 - out <- &RemovedBlock{Hash: c.String(), Error: format.ErrNotFound{Cid: c}.Error()}
59 + out <- &RemovedBlock{Hash: c.String(), Error: format.ErrNotFound{Cid: c}}
60 continue
61 }
62
63 err = blocks.DeleteBlock(ctx, c)
64 if err != nil {
64 - out <- &RemovedBlock{Hash: c.String(), Error: err.Error()}
65 + out <- &RemovedBlock{Hash: c.String(), Error: err}
66 } else if !opts.Quiet {
67 out <- &RemovedBlock{Hash: c.String()}
68 }
@@ -79,7 +80,7 @@ func FilterPinned(ctx context.Context, pins pin.Pinner, out chan<- interface{},
80 stillOkay := make([]cid.Cid, 0, len(cids))
81 res, err := pins.CheckIfPinned(ctx, cids...)
82 if err != nil {
82 - out <- &RemovedBlock{Error: fmt.Sprintf("pin check failed: %s", err)}
83 + out <- &RemovedBlock{Error: fmt.Errorf("pin check failed: %w", err)}
84 return nil
85 }
86 for _, r := range res {
@@ -88,7 +89,7 @@ func FilterPinned(ctx context.Context, pins pin.Pinner, out chan<- interface{},
89 } else {
90 out <- &RemovedBlock{
91 Hash: r.Key.String(),
91 - Error: r.String(),
92 + Error: errors.New(r.String()),
93 }
94 }
95 }
@@ -107,11 +108,11 @@ func ProcRmOutput(next func() (interface{}, error), sout io.Writer, serr io.Writ
108 return err
109 }
110 r := res.(*RemovedBlock)
110 - if r.Hash == "" && r.Error != "" {
111 - return fmt.Errorf("aborted: %s", r.Error)
112 - } else if r.Error != "" {
111 + if r.Hash == "" && r.Error != nil {
112 + return fmt.Errorf("aborted: %w", r.Error)
113 + } else if r.Error != nil {
114 someFailed = true
114 - fmt.Fprintf(serr, "cannot remove %s: %s\n", r.Hash, r.Error)
115 + fmt.Fprintf(serr, "cannot remove %s: %v\n", r.Hash, r.Error)
116 } else {
117 fmt.Fprintf(sout, "removed %s\n", r.Hash)
118 }
core/commands/block.go
+30 -5
@@ -8,7 +8,6 @@ import (
8
9 files "github.com/ipfs/go-ipfs-files"
10
11 - util "github.com/ipfs/go-ipfs/blocks/blockstoreutil"
11 cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
12 "github.com/ipfs/go-ipfs/core/commands/cmdutils"
13
@@ -213,6 +212,11 @@ const (
212 blockQuietOptionName = "quiet"
213 )
214
215 +type removedBlock struct {
216 + Hash string `json:",omitempty"`
217 + Error string `json:",omitempty"`
218 +}
219 +
220 var blockRmCmd = &cmds.Command{
221 Helptext: cmds.HelpText{
222 Tagline: "Remove IPFS block(s).",
@@ -246,7 +250,7 @@ It takes a list of base58 encoded multihashes to remove.
250
251 err = api.Block().Rm(req.Context, rp, options.Block.Force(force))
252 if err != nil {
249 - if err := res.Emit(&util.RemovedBlock{
253 + if err := res.Emit(&removedBlock{
254 Hash: rp.Cid().String(),
255 Error: err.Error(),
256 }); err != nil {
@@ -256,7 +260,7 @@ It takes a list of base58 encoded multihashes to remove.
260 }
261
262 if !quiet {
259 - err := res.Emit(&util.RemovedBlock{
263 + err := res.Emit(&removedBlock{
264 Hash: rp.Cid().String(),
265 })
266 if err != nil {
@@ -269,8 +273,29 @@ It takes a list of base58 encoded multihashes to remove.
273 },
274 PostRun: cmds.PostRunMap{
275 cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error {
272 - return util.ProcRmOutput(res.Next, os.Stdout, os.Stderr)
276 + someFailed := false
277 + for {
278 + res, err := res.Next()
279 + if err == io.EOF {
280 + break
281 + } else if err != nil {
282 + return err
283 + }
284 + r := res.(*removedBlock)
285 + if r.Hash == "" && r.Error != "" {
286 + return fmt.Errorf("aborted: %s", r.Error)
287 + } else if r.Error != "" {
288 + someFailed = true
289 + fmt.Fprintf(os.Stderr, "cannot remove %s: %s\n", r.Hash, r.Error)
290 + } else {
291 + fmt.Fprintf(os.Stdout, "removed %s\n", r.Hash)
292 + }
293 + }
294 + if someFailed {
295 + return fmt.Errorf("some blocks not removed")
296 + }
297 + return nil
298 },
299 },
275 - Type: util.RemovedBlock{},
300 + Type: removedBlock{},
301 }
core/coreapi/block.go
+2 -4
@@ -107,10 +107,8 @@ func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRm
107 return errors.New("got unexpected output from util.RmBlocks")
108 }
109
110 - // Because errors come as strings we lose information about
111 - // the error type.
112 - if remBlock.Error != "" {
113 - return errors.New(remBlock.Error)
110 + if remBlock.Error != nil {
111 + return remBlock.Error
112 }
113 return nil
114 case <-ctx.Done():