Skip to content

Commit 28843c9

Browse files
authored
Merge pull request #16 from zostay/deferred-error
feat: adding deferred.Error()
2 parents bf41a03 + f8de641 commit 28843c9

File tree

8 files changed

+101
-4
lines changed

8 files changed

+101
-4
lines changed

.github/workflows/prepare.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- uses: actions/checkout@v4
1313
- uses: actions/setup-go@v5
1414
with:
15-
go-version: 1.19
15+
go-version: 1.20
1616
- name: Release Verseion
1717
run: echo $RELEASE_VERSION=$(echo $GITHUB_REF_NAME | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+.*$') >> $GITHUB_ENV
1818
- name: Version Check

.github/workflows/release.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
- uses: actions/checkout@v4
1616
- uses: actions/setup-go@v5
1717
with:
18-
go-version: 1.19
18+
go-version: 1.20
1919
- name: Release Verseion
2020
run: echo $RELEASE_VERSION=$(echo $GITHUB_REF_NAME | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+.*$') >> $GITHUB_ENV
2121
- name: Version Check

.github/workflows/test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
- uses: actions/checkout@v4
1111
- uses: actions/setup-go@v5
1212
with:
13-
go-version: 1.19
13+
go-version: '1.20'
1414
cache: false
1515
- uses: golangci/golangci-lint-action@v6
1616
with:

Changes.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## WIP TBD
2+
3+
* :boom: Breaking Change :boom:: Now requires Go 1.20.
4+
* Adding deferred.Error for helping with deferred error handling.
5+
16
## v0.6.0 2023-08-12
27

38
* Adding slices.Insert

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ There are a lot of common operations simply missing from the Golang builtin
44
library. This makes up for that deficiency. Here's a summary of some of the
55
provided tools:
66

7+
## Deferred Handling
8+
9+
Handling deferred functions is a bit of a pain. This provides a way to handle
10+
certain deferred calls with a little less hassle:
11+
12+
* `Error` (allows capturing both errors that may occur during defer)
13+
714
## FileSystem Operations
815

916
The built-in `io/fs` package is fine for reading files, but is missing write interfaces. This provides them:

deferred/error.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package deferred
2+
3+
import "errors"
4+
5+
// Error is intended to be used in cases where you have a deferred function that
6+
// returns an error and you want to capture that error, but you may have an error
7+
// that has already occurred and need to capture that too:
8+
//
9+
// func ProcessFile(name string) (err error) {
10+
// var r io.Reader
11+
// r, err = os.Open(name)
12+
// if err != nil {
13+
// return
14+
// }
15+
// defer deferred.Error(&err, r.Close())
16+
//
17+
// // process file
18+
// return
19+
// }
20+
//
21+
// Now, both errors can be captured without a lot of gymnastics.
22+
func Error(err *error, deferErr error) {
23+
if deferErr == nil {
24+
return
25+
}
26+
27+
if *err == nil {
28+
*err = deferErr
29+
return
30+
}
31+
32+
*err = errors.Join(*err, deferErr)
33+
}

deferred/error_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package deferred_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
9+
"github.com/zostay/go-std/deferred"
10+
)
11+
12+
func TestError(t *testing.T) {
13+
t.Parallel()
14+
15+
errors := []error{
16+
fmt.Errorf("error 1"),
17+
fmt.Errorf("error 2"),
18+
}
19+
20+
cases := []struct {
21+
first, second error
22+
name string
23+
}{
24+
{nil, nil, "nil-nil"},
25+
{errors[0], nil, "error-nil"},
26+
{nil, errors[0], "nil-error"},
27+
{errors[0], errors[1], "error-error"},
28+
}
29+
30+
for _, c := range cases {
31+
c := c
32+
t.Run(c.name, func(t *testing.T) {
33+
t.Parallel()
34+
35+
err := c.first
36+
deferred.Error(&err, c.second)
37+
38+
if c.first == nil && c.second == nil {
39+
assert.NoError(t, err, c.name)
40+
return
41+
}
42+
43+
assert.Error(t, err)
44+
if c.first != nil {
45+
assert.ErrorIs(t, err, c.first)
46+
}
47+
if c.second != nil {
48+
assert.ErrorIs(t, err, c.second)
49+
}
50+
})
51+
}
52+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/zostay/go-std
22

3-
go 1.19
3+
go 1.20
44

55
require (
66
github.com/stretchr/testify v1.8.2

0 commit comments

Comments
 (0)