One Way To Do It — Six Variations

1. Standard Idiom

// Drive to the store
shopper, err := shopper.Drive(FuelNeededToGetToStore)
if err != nil {
log.Fatalf("could not complete shopping: %s", err)
}
// Buy the eggs
shopper, err = shopper.BuyEggs(EggsRequired)
if err != nil {
log.Fatalf("could not complete shopping: %s", err)
}
// Drive home
shopper, err = shopper.Drive(FuelNeededToGetHome)
if err != nil {
log.Fatalf("could not complete shopping: %s", err)
}

2. Common Error Handler Function

func FatalIfErrNotNil(err error) {
if err != nil {
log.Fatalf("could not complete shopping: %s", err)
}
}
...
shopper, err := shopper.Drive(FuelNeededToGetToStore)
FatalIfErrNotNil(err)
shopper, err = shopper.BuyEggs(EggsRequired)
FatalIfErrNotNil(err)
shopper, err = shopper.Drive(FuelNeededToGetHome)
FatalIfErrNotNil(err)
    shopper, err := shopper.Drive(FuelNeededToGetToStore)
if ErrorHandled(err) {
return ...
}

3. Include Error Check In Methods

func (s Shopper) Drive(fuelRequired int, err error) (Shopper, error) {
if err != nil {
return s, err
}
... actual logic of this method ...
}
shopper, err := shopper.Drive(FuelNeededToGetToStore, nil)
shopper, err = shopper.BuyEggs(EggsRequired, err)
shopper, err = shopper.Drive(FuelNeededToGetHome, err)
if err != nil {
log.Fatalf("could not complete shopping: %s", err)
}

4. Use Functions Instead Of Methods

func Drive(s Shopper, fuelRequired int, err error) (Shopper, error) {
if err != nil {
return s, err
}

5. Use A Function Generator To Factor Out Error Handling

func ErrCheckFunc(f func(Shopper, int) (Shopper, error)) func(error, Shopper, int) (error, Shopper) {    return func(err error, s Shopper, arg int) (error, Shopper) {
if err != nil {
return err, s
}
s, err = f(s, arg)
return err, s
}
}
drive := ErrCheckFunc(Drive)
buy := ErrCheckFunc(BuyEggs)
err, shopper := drive(nil, shopper, FuelNeededToGetToStore)
err, shopper = buy(err, shopper, EggsRequired)
err, shopper = drive(err, shopper, FuelNeededToGetHome)
if err != nil {
log.Fatalf("could not complete shopping: %s", err)
}

6. A Single Line Of Action

func ErrCheckFunc(f func(Shopper, int) (Shopper, error), arg int) func(error, Shopper) (error, Shopper) {    return func(err error, s Shopper) (error, Shopper) {
if err != nil {
return err, s
}
s, err = f(s, arg)
return err, s
}
}
driveToStore := ErrCheckFunc(Drive, FuelNeededToGetToStore)
buyEggs := ErrCheckFunc(BuyEggs, EggsRequired)
driveHome := ErrCheckFunc(Drive, FuelNeededToGetHome)
err, shopper := driveHome(buyEggs(driveToStore(nil, shopper)))if err != nil {
log.Fatalf("could not complete shopping: %s", err)
}
func numbers() (int, int) {
return 1, 1
}
func add(a, b int) int {
return a + b
}
answer := add(numbers())
err, shopper := driveHome(buyEggs(driveToStore(nil, shopper)))

Conclusion

Bonus Round

func ProcessSteps(s Shopper, steps ...func(Shopper) (Shopper, error)) (Shopper, error) {
for _, oneStep := range steps {
var err error // avoid shadowing s
s, err = oneStep(s)
if err != nil {
return s, err
}
}
return s, nil
}
shopper, err := ProcessSteps(shopper,
driveToStore,
buyEggs,
driveHome,
)
if err != nil {
log.Fatalf("could not complete shopping: %s", err)
}

--

--

--

Web/database engineer/gopher. Cycling, photos, yada, yada.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

[C++] be care of erase(value) of a container, it will erase all of same value.

Corda 5 “The road ahead” — Part 3 — Introduction to the Architecture

Test Driven Development, Should You or Should You not?

How to Get Hired as a Scrum Master?

The Starting block of Web Development

How to flatten your KCC smart contracts?

Week7 — Independent Study Dev Blog

Engineering Hiring at HappyFunCorp: How We Find a Wider Kind of “The Right People”

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Patrick Kelly

Patrick Kelly

Web/database engineer/gopher. Cycling, photos, yada, yada.

More from Medium

Getting started with GO Programming Language — Part Two

A good summary of Go lang basic syntax

[Solution] Exercise: Stringers | A Tour of Go

Generate random strings in Golang