-
Notifications
You must be signed in to change notification settings - Fork 47
Closed
Labels
Description
I've hit a surprising number of cases recently where I wished that multierr.Append would tell me if the append happened or not. It's not so much for dubious micro perf reasons (CPUs being cheap, fast, and plentiful these days), but more on account of simplifying control flow:
- when I don't need to tell if it happened, I can use the inline form like
err = multierr.Append(err, somethingFaliable()) - but if I need to know if
somethingFaliablefailed or not in addition to collecting its error, then I have to break that apart, and do my own nil check - really the hardest part of this, as always, is choosing what to name
someErr;-)
package main
type T struct{}
type Scanable interface {
Scan(...interface{}) bool
}
// harvestT loads T from some Scanable source. Since we really like T, we don't
// let mundane details like parsing errors get in our way; instead we continue
// on to harvest as much T as we can, collecting any errors that we encounter.
func harvestT(iter Scanable) ([]T, error) {
var (
mess string // each string from the db
datum T // each parsed item
data []T // all items parsed
retErr error // any collected errors
)
// with current multierr
for iter.Scan(&mess) {
if parseErr := tryToParse(s, &datum); parseErr != nil {
retErr = multierr.Append(retErr, parseErr)
continue
}
data = append(data, datum)
}
// however what if we could:
for iter.Scan(&mess) {
retErr, failed = multierr.Appended(retErr, parseErr)
if failed {
continue
}
data = append(data, datum)
}
// or even "better" in this case:
for iter.Scan(&mess) {
retErr, failed = multierr.Appended(retErr, parseErr)
if !failed {
data = append(data, datum)
}
}
// alternatively, if we used a *error:
for iter.Scan(&mess) {
if multierr.AppendInto(&retErr, parseErr) {
continue
}
data = append(data, datum)
}
// which of course could be simplified in our singleton case (you wouldn't
// want to do this if you had more than one faliable step in the loop
// body):
for iter.Scan(&mess) {
if !multierr.AppendInto(&retErr, parseErr) {
data = append(data, datum)
}
}
return data, retErr
}rf and shabbyrobe