Skip to content

Commit 5e001b8

Browse files
committed
Move to go 1.20 error slice unwrapping
Build tag it to continue supporting older versions of go. Fix a bug in the old Unwrap() method's implementation that would panic if there were zero errors listed, due to an out of bounds index.
1 parent 4c713a4 commit 5e001b8

File tree

3 files changed

+79
-29
lines changed

3 files changed

+79
-29
lines changed

errors_unwrap_go1.19_earlier.go

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2025 Vimeo
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
//go:build !go1.20
16+
17+
package retry
18+
19+
import "errors"
20+
21+
// Unwrap returns the most recent error that occured during retrying.
22+
func (e *Errors) Unwrap() error {
23+
if len(e.Errs) == 0 {
24+
return nil
25+
}
26+
return e.Errs[len(e.Errs)-1]
27+
}
28+
29+
// Is will return true if any of the underlying errors matches the target. See
30+
// https://golang.org/pkg/errors/#Is
31+
func (e *Errors) Is(target error) bool {
32+
for _, err := range e.Errs {
33+
if errors.Is(err, target) {
34+
return true
35+
}
36+
}
37+
return false
38+
}
39+
40+
// As will return true if any of the underlying errors matches the target and
41+
// sets the argument to that error specifically. It returns false otherwise,
42+
// leaving the argument unchanged. See https://golang.org/pkg/errors/#As
43+
func (e *Errors) As(target interface{}) bool {
44+
for _, err := range e.Errs {
45+
if errors.As(err, target) {
46+
return true
47+
}
48+
}
49+
return false
50+
}

errors_unwrap_go1.20.go

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2025 Vimeo
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
//go:build go1.20
16+
17+
package retry
18+
19+
// Unwrap returns the errors that occured during retrying.
20+
func (e *Errors) Unwrap() []error {
21+
if len(e.Errs) == 0 {
22+
return nil
23+
}
24+
out := make([]error, len(e.Errs))
25+
for i, err := range e.Errs {
26+
out[i] = err
27+
}
28+
return out
29+
}

retry.go

-29
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package retry
1616

1717
import (
1818
"context"
19-
"errors"
2019
"fmt"
2120
"time"
2221

@@ -147,34 +146,6 @@ type Errors struct {
147146
Errs []*Error
148147
}
149148

150-
// Unwrap returns the most recent error that occured during retrying.
151-
func (e *Errors) Unwrap() error {
152-
return e.Errs[len(e.Errs)-1]
153-
}
154-
155-
// Is will return true if any of the underlying errors matches the target. See
156-
// https://golang.org/pkg/errors/#Is
157-
func (e *Errors) Is(target error) bool {
158-
for _, err := range e.Errs {
159-
if errors.Is(err, target) {
160-
return true
161-
}
162-
}
163-
return false
164-
}
165-
166-
// As will return true if any of the underlying errors matches the target and
167-
// sets the argument to that error specifically. It returns false otherwise,
168-
// leaving the argument unchanged. See https://golang.org/pkg/errors/#As
169-
func (e *Errors) As(target interface{}) bool {
170-
for _, err := range e.Errs {
171-
if errors.As(err, target) {
172-
return true
173-
}
174-
}
175-
return false
176-
}
177-
178149
// Error implements the error interface.
179150
func (e *Errors) Error() string {
180151
return fmt.Sprintf("errors retrying: %+v", e.Errs)

0 commit comments

Comments
 (0)