From 0ef9c39b4387cfd7cd70731d59abad4171f74473 Mon Sep 17 00:00:00 2001 From: Wonyoung Ju Date: Sat, 28 Jul 2018 23:33:11 +0900 Subject: [PATCH] Make public --- .travis.yml | 3 +++ License | 21 +++++++++++++++ README.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ multierr.go | 25 +++++++++++++++++ mutierr_test.go | 23 ++++++++++++++++ 5 files changed, 144 insertions(+) create mode 100644 .travis.yml create mode 100644 License create mode 100644 README.md create mode 100644 multierr.go create mode 100644 mutierr_test.go diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..8b3da87 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: go +go: + - "1.10" diff --git a/License b/License new file mode 100644 index 0000000..dca5250 --- /dev/null +++ b/License @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 getogrand + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..94eb885 --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +# multierr + +[![GoDoc](https://godoc.org/github.com/getogrand/multierr?status.svg)](https://godoc.org/github.com/getogrand/multierr) +[![Build Status](https://travis-ci.org/getogrand/multierr.svg?branch=master)](https://travis-ci.org/getogrand/multierr) + +Package multierr introduce a simple way to join multiple errors as an error. + +## Installation + +Run `go get github.com/getogrand/multierr`. + +## Usage + +The `multierr.Join()` combine multiple errors to an error. + +You can report multiple errors as an joined error to the caller using `multierr.Join()`. + +```go +import "github.com/getogrand/multierr" + +var ee []error + +up := ReservationUserPush{} +n := ReservationAlarmNoti{} + +if err := up.Send(); err != nil { + ee = append(ee, + fmt.Errorf("send reservation %v push to user: %v", n.Reservation.ID, err)) +} + +if err := n.sendShopAlarm(); err != nil { + ee = append(ee, fmt.Errorf( + "send shop alarm message of reservation %v: %v", n.Reservation.ID, err)) +} + +if err := n.sendUserAlarm(); err != nil { + ee = append(ee, fmt.Errorf( + "send user alarm message of reservation %v: %v", n.Reservation.ID, err)) +} + +return multierr.Join(ee) // error{"3 errors occured: send reservation 1 push to user: connection fail, send shop alarm message of reservation 1: connection fail, send user alarm message of reservation 1: connection fail"} +``` + +It is really useful when you run errorable operation in for-loop. + +```go +import "github.com/getogrand/multierr" + +func SliceConvAtoi32(aa []string) ([]int32, error) { + errs := []error{} + ii := []int32{} + for _, a := range aa { + i, err := strconv.Atoi(a) + if err != nil { + errs = append(errs, fmt.Errorf("convert %q to int: %v", a, err)) + continue + } + ii = append(ii, int32(i)) + } + + if len(errs) > 0 { + return []int32{}, multierr.Join(errs) + } + return ii, nil +} +``` + +## Extracted From [heybeauty](https://heybeauty.me) + +## License + +Released under the [MIT License](https://github.com/getogrand/multierr/blob/master/License) diff --git a/multierr.go b/multierr.go new file mode 100644 index 0000000..62bf876 --- /dev/null +++ b/multierr.go @@ -0,0 +1,25 @@ +// Package multierr introduce a simple way to join multiple errors as an error. +package multierr + +import ( + "fmt" + "strings" +) + +// Join combine multiple errors to an error. +// +// Error that joined have error string follow below format. +// +// `2 errors occured: open file abc.png, close connection of db 'test_db'` +func Join(errs []error) error { + if len(errs) == 0 { + return nil + } + + var msgs []string + for _, e := range errs { + msgs = append(msgs, e.Error()) + } + joinedmsg := strings.Join(msgs, ", ") + return fmt.Errorf("%d errors occured: %s", len(errs), joinedmsg) +} diff --git a/mutierr_test.go b/mutierr_test.go new file mode 100644 index 0000000..2690816 --- /dev/null +++ b/mutierr_test.go @@ -0,0 +1,23 @@ +package multierr_test + +import ( + "fmt" + "testing" + + "github.com/getogrand/multierr" + "github.com/stretchr/testify/assert" +) + +func TestJoin(t *testing.T) { + errors := []error{ + fmt.Errorf("this is error 1"), + fmt.Errorf("this is error 2"), + fmt.Errorf("this is error 3"), + } + + joinderr := multierr.Join(errors) + assert.Error(t, joinderr) + assert.Equal(t, + "3 errors occured: this is error 1, this is error 2, this is error 3", + joinderr.Error()) +}