Skip to content

Commit

Permalink
feat(erros): errors.Join on older go versions
Browse files Browse the repository at this point in the history
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
  • Loading branch information
caarlos0 committed Jan 17, 2024
1 parent ba5e52e commit 5da6079
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 1 deletion.
9 changes: 9 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,12 @@ updates:
commit-message:
prefix: "feat"
include: "scope"
- package-ecosystem: "gomod"
directory: "/errors"
schedule:
interval: "daily"
labels:
- "dependencies"
commit-message:
prefix: "feat"
include: "scope"
17 changes: 17 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,20 @@ jobs:
cache-dependency-path: ./editor.sum
- run: go build -v ./...
- run: go test -race -v ./...
errors:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: ./errors
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: ./errors/go.mod
cache: true
cache-dependency-path: ./errors.sum
- run: go build -v ./...
- run: go test -race -v ./...
3 changes: 3 additions & 0 deletions errors/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/charmbracelet/x/errors

go 1.21.5
46 changes: 46 additions & 0 deletions errors/join.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package errors

import "strings"

// Join returns an error that wraps the given errors.
// Any nil error values are discarded.
// Join returns nil if every value in errs is nil.
// The error formats as the concatenation of the strings obtained
// by calling the Error method of each element of errs, with a newline
// between each string.
//
// A non-nil error returned by Join implements the Unwrap() []error method.
//
// This is copied from Go 1.20 errors.Unwrap, with some tuning to avoid using unsafe.
// The main goal is to have this available in older Go versions.
func Join(errs ...error) error {
var nonNil []error
for _, err := range errs {
if err == nil {
continue
}
nonNil = append(nonNil, err)
}
if len(nonNil) == 0 {
return nil
}
return &joinError{
errs: nonNil,
}
}

type joinError struct {
errs []error
}

func (e *joinError) Error() string {
strs := make([]string, 0, len(e.errs))
for _, err := range e.errs {
strs = append(strs, err.Error())
}
return strings.Join(strs, "\n")
}

func (e *joinError) Unwrap() []error {
return e.errs
}
41 changes: 41 additions & 0 deletions errors/join_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package errors

import (
"errors"
"fmt"
"testing"
)

func TestJoin(t *testing.T) {
t.Run("nil", func(t *testing.T) {
err := Join(nil, nil, nil)
if err != nil {
t.Errorf("expected nil, got %v", err)
}
})
t.Run("one err", func(t *testing.T) {
expected := fmt.Errorf("fake")
err := Join(nil, expected, nil)
if !errors.Is(err, expected) {
t.Errorf("expected %v, got %v", expected, err)
}
if s := err.Error(); s != expected.Error() {
t.Errorf("expected %s, got %s", expected, err)
}
})
t.Run("many errs", func(t *testing.T) {
expected1 := fmt.Errorf("fake 1")
expected2 := fmt.Errorf("fake 2")
err := Join(nil, expected1, nil, nil, expected2, nil)
if !errors.Is(err, expected1) {
t.Errorf("expected %v, got %v", expected1, err)
}
if !errors.Is(err, expected2) {
t.Errorf("expected %v, got %v", expected2, err)
}
expectedS := expected1.Error() + "\n" + expected2.Error()
if s := err.Error(); s != expectedS {
t.Errorf("expected %s, got %s", expectedS, err)
}
})
}
3 changes: 2 additions & 1 deletion go.work
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
go 1.21
go 1.21.5

use (
./editor
./errors
./exp/higherorder
./exp/ordered
./exp/slice
Expand Down

0 comments on commit 5da6079

Please sign in to comment.