@cryptotaxi247 / kubo / commits / 002cf5128

fix silent refs failure

Jeromy committed May 19, 2015 at 17:58 UTC 002cf5128e699c6b17858d61156944c5d04aaa0a
2 files changed +47 -51
cmd/ipfs/main.go
+6 -1
@@ -154,7 +154,12 @@ func main() {
154 }
155
156 // everything went better than expected :)
157 - io.Copy(os.Stdout, output)
157 + _, err = io.Copy(os.Stdout, output)
158 + if err != nil {
159 + printErr(err)
160 +
161 + os.Exit(1)
162 + }
163 }
164
165 func (i *cmdInvocation) Run(ctx context.Context) (output io.Reader, err error) {
core/commands/refs.go
+41 -50
@@ -2,9 +2,10 @@ package commands
2
3 import (
4 "bytes"
5 + "errors"
6 + "fmt"
7 "io"
8 "strings"
7 - "sync"
9
10 context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
11 cmds "github.com/ipfs/go-ipfs/commands"
@@ -91,14 +92,14 @@ Note: list all refs recursively with -r.
92 return
93 }
94
94 - piper, pipew := io.Pipe()
95 - eptr := &ErrPassThroughReader{R: piper}
95 + out := make(chan interface{})
96 + res.SetOutput((<-chan interface{})(out))
97
98 go func() {
98 - defer pipew.Close()
99 + defer close(out)
100
101 rw := RefWriter{
101 - W: pipew,
102 + out: out,
103 DAG: n.DAG,
104 Ctx: ctx,
105 Unique: unique,
@@ -109,14 +110,40 @@ Note: list all refs recursively with -r.
110
111 for _, o := range objs {
112 if _, err := rw.WriteRefs(o); err != nil {
112 - eptr.SetError(err)
113 + out <- &RefWrapper{Err: err.Error()}
114 return
115 }
116 }
117 }()
118 + },
119 + Marshalers: cmds.MarshalerMap{
120 + cmds.Text: func(res cmds.Response) (io.Reader, error) {
121 + outChan, ok := res.Output().(<-chan interface{})
122 + if !ok {
123 + return nil, u.ErrCast()
124 + }
125
118 - res.SetOutput(eptr)
126 + marshal := func(v interface{}) (io.Reader, error) {
127 + obj, ok := v.(*RefWrapper)
128 + if !ok {
129 + fmt.Println("%#v", v)
130 + return nil, u.ErrCast()
131 + }
132 +
133 + if obj.Err != "" {
134 + return nil, errors.New(obj.Err)
135 + }
136 +
137 + return strings.NewReader(obj.Ref), nil
138 + }
139 +
140 + return &cmds.ChannelMarshaler{
141 + Channel: outChan,
142 + Marshaler: marshal,
143 + }, nil
144 + },
145 },
146 + Type: RefWrapper{},
147 }
148
149 var RefsLocalCmd = &cmds.Command{
@@ -143,7 +170,6 @@ Displays the hashes of all local objects.
170 }
171
172 piper, pipew := io.Pipe()
146 - eptr := &ErrPassThroughReader{R: piper}
173
174 go func() {
175 defer pipew.Close()
@@ -151,13 +177,13 @@ Displays the hashes of all local objects.
177 for k := range allKeys {
178 s := k.Pretty() + "\n"
179 if _, err := pipew.Write([]byte(s)); err != nil {
154 - eptr.SetError(err)
180 + log.Error("pipe write error: ", err)
181 return
182 }
183 }
184 }()
185
160 - res.SetOutput(eptr)
186 + res.SetOutput(piper)
187 },
188 }
189
@@ -173,46 +199,13 @@ func objectsForPaths(ctx context.Context, n *core.IpfsNode, paths []string) ([]*
199 return objects, nil
200 }
201
176 -// ErrPassThroughReader is a reader that may return an externally set error.
177 -type ErrPassThroughReader struct {
178 - R io.ReadCloser
179 - err error
180 -
181 - sync.RWMutex
182 -}
183 -
184 -func (r *ErrPassThroughReader) Error() error {
185 - r.RLock()
186 - defer r.RUnlock()
187 - return r.err
188 -}
189 -
190 -func (r *ErrPassThroughReader) SetError(err error) {
191 - r.Lock()
192 - r.err = err
193 - r.Unlock()
194 -}
195 -
196 -func (r *ErrPassThroughReader) Read(buf []byte) (int, error) {
197 - err := r.Error()
198 - if err != nil {
199 - return 0, err
200 - }
201 -
202 - return r.R.Read(buf)
203 -}
204 -
205 -func (r *ErrPassThroughReader) Close() error {
206 - err1 := r.R.Close()
207 - err2 := r.Error()
208 - if err2 != nil {
209 - return err2
210 - }
211 - return err1
202 +type RefWrapper struct {
203 + Ref string
204 + Err string
205 }
206
207 type RefWriter struct {
215 - W io.Writer
208 + out chan interface{}
209 DAG dag.DAGService
210 Ctx context.Context
211
@@ -335,8 +328,6 @@ func (rw *RefWriter) WriteEdge(from, to u.Key, linkname string) error {
328 }
329 s += "\n"
330
338 - if _, err := rw.W.Write([]byte(s)); err != nil {
339 - return err
340 - }
331 + rw.out <- &RefWrapper{Ref: s}
332 return nil
333 }