diff --git a/.github/workflows/prepare.yaml b/.github/workflows/prepare.yaml index 539db34..c93dfee 100644 --- a/.github/workflows/prepare.yaml +++ b/.github/workflows/prepare.yaml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: 1.19 + go-version: 1.20 - name: Release Verseion run: echo $RELEASE_VERSION=$(echo $GITHUB_REF_NAME | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+.*$') >> $GITHUB_ENV - name: Version Check diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f8effff..9f895ff 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: 1.19 + go-version: 1.20 - name: Release Verseion run: echo $RELEASE_VERSION=$(echo $GITHUB_REF_NAME | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+.*$') >> $GITHUB_ENV - name: Version Check diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 5fd0514..752fab0 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: 1.19 + go-version: '1.20' cache: false - uses: golangci/golangci-lint-action@v6 with: diff --git a/Changes.md b/Changes.md index 85667a7..545b651 100644 --- a/Changes.md +++ b/Changes.md @@ -1,3 +1,8 @@ +## WIP TBD + + * :boom: Breaking Change :boom:: Now requires Go 1.20. + * Adding deferred.Error for helping with deferred error handling. + ## v0.6.0 2023-08-12 * Adding slices.Insert diff --git a/README.md b/README.md index e403e6d..b931dd1 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,13 @@ There are a lot of common operations simply missing from the Golang builtin library. This makes up for that deficiency. Here's a summary of some of the provided tools: +## Deferred Handling + +Handling deferred functions is a bit of a pain. This provides a way to handle +certain deferred calls with a little less hassle: + +* `Error` (allows capturing both errors that may occur during defer) + ## FileSystem Operations The built-in `io/fs` package is fine for reading files, but is missing write interfaces. This provides them: diff --git a/deferred/error.go b/deferred/error.go new file mode 100644 index 0000000..be269b4 --- /dev/null +++ b/deferred/error.go @@ -0,0 +1,33 @@ +package deferred + +import "errors" + +// Error is intended to be used in cases where you have a deferred function that +// returns an error and you want to capture that error, but you may have an error +// that has already occurred and need to capture that too: +// +// func ProcessFile(name string) (err error) { +// var r io.Reader +// r, err = os.Open(name) +// if err != nil { +// return +// } +// defer deferred.Error(&err, r.Close()) +// +// // process file +// return +// } +// +// Now, both errors can be captured without a lot of gymnastics. +func Error(err *error, deferErr error) { + if deferErr == nil { + return + } + + if *err == nil { + *err = deferErr + return + } + + *err = errors.Join(*err, deferErr) +} diff --git a/deferred/error_test.go b/deferred/error_test.go new file mode 100644 index 0000000..fec0431 --- /dev/null +++ b/deferred/error_test.go @@ -0,0 +1,52 @@ +package deferred_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/zostay/go-std/deferred" +) + +func TestError(t *testing.T) { + t.Parallel() + + errors := []error{ + fmt.Errorf("error 1"), + fmt.Errorf("error 2"), + } + + cases := []struct { + first, second error + name string + }{ + {nil, nil, "nil-nil"}, + {errors[0], nil, "error-nil"}, + {nil, errors[0], "nil-error"}, + {errors[0], errors[1], "error-error"}, + } + + for _, c := range cases { + c := c + t.Run(c.name, func(t *testing.T) { + t.Parallel() + + err := c.first + deferred.Error(&err, c.second) + + if c.first == nil && c.second == nil { + assert.NoError(t, err, c.name) + return + } + + assert.Error(t, err) + if c.first != nil { + assert.ErrorIs(t, err, c.first) + } + if c.second != nil { + assert.ErrorIs(t, err, c.second) + } + }) + } +} diff --git a/go.mod b/go.mod index 8c2c7a4..5e9d258 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/zostay/go-std -go 1.19 +go 1.20 require ( github.com/stretchr/testify v1.8.2