@@ -3,6 +3,7 @@ package pipe
3
3
import (
4
4
"bytes"
5
5
"context"
6
+ "errors"
6
7
"fmt"
7
8
"io"
8
9
"io/ioutil"
@@ -17,6 +18,13 @@ type Env struct {
17
18
Dir string
18
19
}
19
20
21
+ // FinishEarly is an error that can be returned by a `Stage` to
22
+ // request that the iteration be ended early (possibly without reading
23
+ // all of its input). This "error" is considered a successful return,
24
+ // and is not reported to the caller.
25
+ //nolint:revive
26
+ var FinishEarly = errors .New ("finish stage early" )
27
+
20
28
// Pipeline represents a Unix-like pipe that can include multiple
21
29
// stages, including external processes but also and stages written in
22
30
// Go.
@@ -186,12 +194,27 @@ func (p *Pipeline) Wait() error {
186
194
s := p .stages [i ]
187
195
err := s .Wait ()
188
196
189
- // We want to report the error that is most informative. We
190
- // take that to be the error from the earliest pipeline stage
191
- // that failed of a non-pipe error. If that didn't happen,
192
- // take the error from the last pipeline stage that failed due
193
- // to a pipe error.
194
- if err != nil && (earliestStageErr == nil || ! IsPipeError (err )) {
197
+ // Error handling:
198
+
199
+ if err == nil {
200
+ // No error to handle.
201
+ continue
202
+ }
203
+
204
+ if err == FinishEarly {
205
+ // We ignore `FinishEarly` errors because that is how a
206
+ // stage informs us that it intentionally finished early.
207
+ continue
208
+ }
209
+
210
+ // If we reach this point, then the stage exited with a
211
+ // non-ignorable error. But multiple stages might report
212
+ // errors, and we want to report the one that is most
213
+ // informative. We take that to be the error from the earliest
214
+ // pipeline stage that failed from a non-pipe error. If that
215
+ // didn't happen, take the error from the last pipeline stage
216
+ // that failed due to a pipe error.
217
+ if earliestStageErr == nil || ! IsPipeError (err ) {
195
218
// Overwrite any existing values here so that we end up
196
219
// retaining the last error that we see; i.e., the error
197
220
// that happened earliest in the pipeline.
0 commit comments