Skip to content

Commit

Permalink
Add Close function to Handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
sagikazarmark committed Jul 30, 2019
1 parent fea1e15 commit e333977
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added

- `Close` function to `Handlers`


## [0.21.2] - 2019-07-19

Expand Down
21 changes: 18 additions & 3 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package emperror

import (
"context"

"emperror.dev/errors"
)

// Handler is a generic error handler. It allows applications (and libraries) to handle errors
Expand All @@ -23,13 +25,26 @@ type ContextAwareHandler interface {
type Handlers []Handler

func (h Handlers) Handle(err error) {
for _, handler := range h {
handler.Handle(err)
}
}

// Close calls Close on the underlying handlers (if there is any closable handler).
func (h Handlers) Close() error {
if len(h) < 1 {
return
return nil
}

for _, handler := range h {
handler.Handle(err)
errs := make([]error, len(h))

for i, handler := range h {
if closer, ok := handler.(interface{ Close() error }); ok {
errs[i] = closer.Close()
}
}

return errors.Combine(errs...)
}

// HandlerFunc wraps a function and turns it into an error handler.
Expand Down
74 changes: 74 additions & 0 deletions handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,80 @@ func TestHandlers(t *testing.T) {
}
}

func TestHandlers_NoHandlers(t *testing.T) {
var handler Handlers

err := errors.New("error")

handler.Handle(err)
}

type closableHandler struct {
handler Handler
closeError error
}

func (h *closableHandler) Handle(err error) {
h.handler.Handle(err)
}

func (h *closableHandler) Close() error {
return h.closeError
}

func TestHandlers_Close(t *testing.T) {
t.Run("no_handlers", func(t *testing.T) {
var handler Handlers

err := handler.Close()

if err != nil {
t.Errorf("unexpected error when closing handlers\nactual: %+v", err)
}
})

t.Run("no_closers", func(t *testing.T) {
handler1 := NewTestHandler()
handler2 := NewTestHandler()

handler := Handlers{handler1, handler2}

err := handler.Close()

if err != nil {
t.Errorf("unexpected error when closing handlers\nactual: %+v", err)
}
})

t.Run("no_errors", func(t *testing.T) {
handler1 := &closableHandler{handler: NewTestHandler()}
handler2 := NewTestHandler()

handler := Handlers{handler1, handler2}

err := handler.Close()

if err != nil {
t.Errorf("unexpected error when closing handlers\nactual: %+v", err)
}
})

t.Run("error", func(t *testing.T) {
closeErr := errors.New("close error")

handler1 := &closableHandler{handler: NewTestHandler(), closeError: closeErr}
handler2 := NewTestHandler()

handler := Handlers{handler1, handler2}

err := handler.Close()

if err != closeErr {
t.Errorf("unexpected error when closing handlers\nactual: %#v\nexpected: %#v", err, closeErr)
}
})
}

func TestHandlerFunc(t *testing.T) {
var actual error
log := func(err error) {
Expand Down

0 comments on commit e333977

Please sign in to comment.