Skip to content

Commit

Permalink
Merge pull request #26 from ccremer/options-wrap
Browse files Browse the repository at this point in the history
Add option to disable error wrapping
  • Loading branch information
ccremer committed Dec 27, 2021
2 parents f068907 + f87dfa4 commit 41e5a47
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 5 deletions.
21 changes: 21 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package pipeline

// Option configures the given Pipeline with a behaviour-altering setting.
type Option func(pipeline *Pipeline)

// WithOptions configures the Pipeline with settings.
// The options are applied immediately.
// Options are applied to nested pipelines provided they are set before building the nested pipeline.
// Nested pipelines can be configured with their own options.
func (p *Pipeline) WithOptions(options ...Option) *Pipeline {
for _, option := range options {
option(p)
}
return p
}

// DisableErrorWrapping disables the wrapping of errors that are emitted from pipeline steps.
// This effectively causes Result.Err to be exactly the error as returned from a step.
var DisableErrorWrapping Option = func(pipeline *Pipeline) {
pipeline.disableErrorWrapping = true
}
22 changes: 22 additions & 0 deletions options_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package pipeline

import (
"errors"
"testing"

"github.com/stretchr/testify/assert"
)

func TestPipeline_WithOptions(t *testing.T) {
t.Run("DisableErrorWrapping", func(t *testing.T) {
p := NewPipeline().WithOptions(DisableErrorWrapping)
p.WithSteps(
NewStepFromFunc("disabled error wrapping", func(_ Context) error {
return errors.New("some error")
}),
)
assert.True(t, p.disableErrorWrapping)
result := p.Run()
assert.Equal(t, "some error", result.Err.Error())
})
}
14 changes: 9 additions & 5 deletions pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import (
type (
// Pipeline holds and runs intermediate actions, called "steps".
Pipeline struct {
steps []Step
context Context
beforeHooks []Listener
finalizer ResultHandler
steps []Step
context Context
beforeHooks []Listener
finalizer ResultHandler
disableErrorWrapping bool
}
// Result is the object that is returned after each step and after running a pipeline.
Result struct {
Expand Down Expand Up @@ -87,7 +88,7 @@ func (p *Pipeline) WithSteps(steps ...Step) *Pipeline {
// WithNestedSteps is similar to AsNestedStep, but it accepts the steps given directly as parameters.
func (p *Pipeline) WithNestedSteps(name string, steps ...Step) Step {
return NewStep(name, func(_ Context) Result {
nested := &Pipeline{beforeHooks: p.beforeHooks, steps: steps, context: p.context}
nested := &Pipeline{beforeHooks: p.beforeHooks, steps: steps, context: p.context, disableErrorWrapping: p.disableErrorWrapping}
return nested.Run()
})
}
Expand Down Expand Up @@ -145,6 +146,9 @@ func (p *Pipeline) doRun() Result {
// Abort pipeline without error
return Result{}
}
if p.disableErrorWrapping {
return Result{Err: err}
}
return Result{Err: fmt.Errorf("step '%s' failed: %w", step.Name, err)}
}
}
Expand Down

0 comments on commit 41e5a47

Please sign in to comment.