diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/07-behaviour_error_handling/cmd/beers-cli/main.go b/07-behaviour_error_handling/cmd/beers-cli/main.go index 8fedd45..aa99dfb 100644 --- a/07-behaviour_error_handling/cmd/beers-cli/main.go +++ b/07-behaviour_error_handling/cmd/beers-cli/main.go @@ -13,7 +13,7 @@ import ( func main() { - csvData := flag.Bool("csv", false, "load data from csv") + csvData := flag.Bool("csv", true, "load data from csv") flag.Parse() var repo beerscli.BeerRepo repo = csv.NewRepository() diff --git a/07-behaviour_error_handling/internal/beer.go b/07-behaviour_error_handling/internal/beer.go index 4ed7c21..d7bffcd 100644 --- a/07-behaviour_error_handling/internal/beer.go +++ b/07-behaviour_error_handling/internal/beer.go @@ -2,6 +2,7 @@ package beerscli import ( "encoding/json" + "github.com/CodelyTV/golang-examples/07-behaviour_error_handling/internal/errors" ) // Beer representation of beer into data struct @@ -66,7 +67,7 @@ func (t *BeerType) UnmarshalJSON(b []byte) error { var j string err := json.Unmarshal(b, &j) if err != nil { - return err + return errors.WrapJsonProcessingDataError(err, "can't parser bytes to Json") } *t = toID[j] return nil diff --git a/07-behaviour_error_handling/internal/cli/beers.go b/07-behaviour_error_handling/internal/cli/beers.go index 8f8e666..108c3d0 100644 --- a/07-behaviour_error_handling/internal/cli/beers.go +++ b/07-behaviour_error_handling/internal/cli/beers.go @@ -32,7 +32,10 @@ func InitBeersCmd(repository beerscli.BeerRepo) *cobra.Command { func runBeersFn(repository beerscli.BeerRepo) CobraFn { return func(cmd *cobra.Command, args []string) { beers, err := repository.GetBeers() - if errors.IsDataUnreacheable(err) { + if errors.IsFileErrorType(err) { + log.Fatal(err) + } + if errors.IsFormatDataError(err) { log.Fatal(err) } diff --git a/07-behaviour_error_handling/internal/errors/errortypes.go b/07-behaviour_error_handling/internal/errors/errortypes.go deleted file mode 100644 index eb443cf..0000000 --- a/07-behaviour_error_handling/internal/errors/errortypes.go +++ /dev/null @@ -1,28 +0,0 @@ -package errors - -import ( - "github.com/pkg/errors" -) - -type dataUnreacheable struct { - error -} - -// WrapDataUnreacheable returns an error which wraps err that satisfies -// IsDataUnreacheable() -func WrapDataUnreacheable(err error, format string, args ...interface{}) error { - return &dataUnreacheable{errors.Wrapf(err, format, args...)} -} - -// NewDataUnreacheable returns an error which satisfies IsDataUnreacheable() -func NewDataUnreacheable(format string, args ...interface{}) error { - return &dataUnreacheable{errors.Errorf(format, args...)} -} - -// IsDataUnreacheable reports whether err was created with DataUnreacheablef() or -// NewDataUnreacheable() -func IsDataUnreacheable(err error) bool { - err = errors.Cause(err) - _, ok := err.(*dataUnreacheable) - return ok -} diff --git a/07-behaviour_error_handling/internal/errors/fileerrortype.go b/07-behaviour_error_handling/internal/errors/fileerrortype.go new file mode 100644 index 0000000..90eacee --- /dev/null +++ b/07-behaviour_error_handling/internal/errors/fileerrortype.go @@ -0,0 +1,23 @@ +package errors + +import ( + "github.com/pkg/errors" +) + +type fileDataError struct { + error +} + +func WrapFileDataUError(err error, format string, args ...interface{}) error { + return &fileDataError{errors.Wrapf(err, format, args...)} +} + +func NewFileDataError(format string, args ...interface{}) error { + return &fileDataError{errors.Errorf(format, args...)} +} + +func IsFileErrorType(err error) bool { + err = errors.Cause(err) + _, ok := err.(*fileDataError) + return ok +} diff --git a/07-behaviour_error_handling/internal/errors/formaterrortype.go b/07-behaviour_error_handling/internal/errors/formaterrortype.go new file mode 100644 index 0000000..0c094a8 --- /dev/null +++ b/07-behaviour_error_handling/internal/errors/formaterrortype.go @@ -0,0 +1,23 @@ +package errors + +import ( + "github.com/pkg/errors" +) + +type formatDataError struct { + error +} + +func WrapFormatDataError(err error, format string, args ...interface{}) error { + return &formatDataError{errors.Wrapf(err, format, args...)} +} + +func NewFormatDataError(format string, args ...interface{}) error { + return &formatDataError{errors.Errorf(format, args...)} +} + +func IsFormatDataError(err error) bool { + err = errors.Cause(err) + _, ok := err.(*formatDataError) + return ok +} diff --git a/07-behaviour_error_handling/internal/errors/httperrortype.go b/07-behaviour_error_handling/internal/errors/httperrortype.go new file mode 100644 index 0000000..8908421 --- /dev/null +++ b/07-behaviour_error_handling/internal/errors/httperrortype.go @@ -0,0 +1,23 @@ +package errors + +import ( + "github.com/pkg/errors" +) + +type httpDataError struct { + error +} + +func WrapHttpDataError(err error, format string, args ...interface{}) error { + return &httpDataError{errors.Wrapf(err, format, args...)} +} + +func NewHttpDataError(format string, args ...interface{}) error { + return &httpDataError{errors.Errorf(format, args...)} +} + +func IsHttpDataError(err error) bool { + err = errors.Cause(err) + _, ok := err.(*httpDataError) + return ok +} diff --git a/07-behaviour_error_handling/internal/errors/jsonprocessingerrortype.go b/07-behaviour_error_handling/internal/errors/jsonprocessingerrortype.go new file mode 100644 index 0000000..1f61bc9 --- /dev/null +++ b/07-behaviour_error_handling/internal/errors/jsonprocessingerrortype.go @@ -0,0 +1,23 @@ +package errors + +import ( + "github.com/pkg/errors" +) + +type jsonProcessingDataError struct { + error +} + +func WrapJsonProcessingDataError(err error, format string, args ...interface{}) error { + return &jsonProcessingDataError{errors.Wrapf(err, format, args...)} +} + +func NewJsonProcessingDataError(format string, args ...interface{}) error { + return &jsonProcessingDataError{errors.Errorf(format, args...)} +} + +func IsJsonProcessingDataError(err error) bool { + err = errors.Cause(err) + _, ok := err.(*jsonProcessingDataError) + return ok +} diff --git a/07-behaviour_error_handling/internal/storage/csv/repository.go b/07-behaviour_error_handling/internal/storage/csv/repository.go index cb1e7cc..ae0bba9 100644 --- a/07-behaviour_error_handling/internal/storage/csv/repository.go +++ b/07-behaviour_error_handling/internal/storage/csv/repository.go @@ -2,6 +2,7 @@ package csv import ( "bufio" + "github.com/CodelyTV/golang-examples/07-behaviour_error_handling/internal/errors" "os" "strconv" "strings" @@ -19,7 +20,12 @@ func NewRepository() beerscli.BeerRepo { // GetBeers fetch beers data from csv func (r *repository) GetBeers() ([]beerscli.Beer, error) { - f, _ := os.Open("07-behaviour_error_handling/data/beers.csv") + f, err := os.Open("07-behaviour_error_handling/data/beers2.csv") + + if err != nil { + return nil, errors.WrapFileDataUError(err, "error getting beers to %s", "csv data") + } + reader := bufio.NewReader(f) var beers []beerscli.Beer @@ -27,7 +33,11 @@ func (r *repository) GetBeers() ([]beerscli.Beer, error) { for line := readLine(reader); line != nil; line = readLine(reader) { values := strings.Split(string(line), ",") - productID, _ := strconv.Atoi(values[0]) + productID, err := strconv.Atoi(values[0]) + + if err != nil { + return nil, errors.WrapFormatDataError(err, "can't format product Id with Atoi method") + } beer := beerscli.NewBeer( productID, @@ -47,5 +57,6 @@ func (r *repository) GetBeers() ([]beerscli.Beer, error) { func readLine(reader *bufio.Reader) (line []byte) { line, _, _ = reader.ReadLine() + return } diff --git a/07-behaviour_error_handling/internal/storage/ontario/repository.go b/07-behaviour_error_handling/internal/storage/ontario/repository.go index ea6608c..4696c42 100644 --- a/07-behaviour_error_handling/internal/storage/ontario/repository.go +++ b/07-behaviour_error_handling/internal/storage/ontario/repository.go @@ -27,17 +27,17 @@ func NewOntarioRepository() beerscli.BeerRepo { func (b *beerRepo) GetBeers() (beers []beerscli.Beer, err error) { response, err := http.Get(fmt.Sprintf("%v%v", b.url, productsEndpoint)) if err != nil { - return nil, errors.WrapDataUnreacheable(err, "error getting response to %s", productsEndpoint) + return nil, errors.WrapHttpDataError(err, "error getting response to %s", productsEndpoint) } contents, err := ioutil.ReadAll(response.Body) if err != nil { - return nil, errors.WrapDataUnreacheable(err, "error reading the response from %s", productsEndpoint) + return nil, errors.WrapHttpDataError(err, "error reading the response from %s", productsEndpoint) } err = json.Unmarshal(contents, &beers) if err != nil { - return nil, errors.WrapDataUnreacheable(err, "can't parsing response into beers") + return nil, errors.WrapJsonProcessingDataError(err, "can't parsing response into beers") } return }