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
}