Proposal Details

Ignoring certain errors is a relatively common operation.

Some examples include:

var tr *tar.Reader = ...
for {
    th, err := tr.Next()
    if err := nil {
        if err == io.EOF {
            return nil
        }
        return err
    }
    ...
}
var tx *sql.Tx = ...
if err := tx.QueryRow(ctx, query, &res); err != nil {
    if errors.Is(err, sql.ErrNoRows) {
        return nil
    }
    return err
}
... // use res

I propose the addition of the following helper function:

// Ignore returns nil if err matches any error in targets,
// otherwise it returns err as is.
func Ignore(err error, targets error...) error {
    for _, target := range targets {
        if Is(err, target) {
            return nil
        }
    }
    return err
}

While this signature doesn't statically prevent accidental swapping of the arguments, it follows a similar pattern as errors.Is, which has exactly the same problem.

With this helper, the above examples could be simplified as:

var tr *tar.Reader = ...
for {
    th, err := tr.Next()
    if err := nil {
        return errors.Ignore(err, io.EOF)
    }
    ...
}
var tx *sql.Tx = ...
if err := tx.QueryRow(ctx, query, &res); err != nil {
    return errors.Ignore(err, sql.ErrNoRows)
}
... // use res

Some more evidence of the utility of this: * cmd/gofmt: return a proper error for empty Go files

Comment From: gabyhelp

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)