hooks: don't skip entire chain if a hook fails

This commit is contained in:
Simon Eskildsen 2017-02-06 20:12:41 -05:00
parent 080ca65fb5
commit af41a51636
4 changed files with 35 additions and 3 deletions

View File

@ -1,3 +1,7 @@
# 0.11.2
* bug: don't skip hooks on failure (#474)
# 0.11.1 # 0.11.1
* bug: fix tty detection with custom out (#471) * bug: fix tty detection with custom out (#471)

View File

@ -95,7 +95,7 @@ func (entry Entry) log(level Level, msg string) {
if err := entry.Logger.Hooks.Fire(level, &entry); err != nil { if err := entry.Logger.Hooks.Fire(level, &entry); err != nil {
entry.Logger.mu.Lock() entry.Logger.mu.Lock()
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) fmt.Fprintf(os.Stderr, "Failed to fire hook(s): %v\n", err)
entry.Logger.mu.Unlock() entry.Logger.mu.Unlock()
} }
buffer = bufferPool.Get().(*bytes.Buffer) buffer = bufferPool.Get().(*bytes.Buffer)

View File

@ -1,6 +1,7 @@
package logrus package logrus
import ( import (
"errors"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -120,3 +121,24 @@ func TestErrorHookShouldFireOnError(t *testing.T) {
assert.Equal(t, hook.Fired, true) assert.Equal(t, hook.Fired, true)
}) })
} }
type FailingHook struct {
TestHook
}
func (hook *FailingHook) Fire(entry *Entry) error {
return errors.New("sad walrus")
}
func TestHookShouldFireAfterFailureHook(t *testing.T) {
failureHook := new(FailingHook)
hook := new(TestHook)
LogAndAssertJSON(t, func(log *Logger) {
log.Hooks.Add(failureHook)
log.Hooks.Add(hook)
log.Error("test")
}, func(fields Fields) {
assert.Equal(t, hook.Fired, true)
})
}

View File

@ -1,5 +1,9 @@
package logrus package logrus
import (
"fmt"
)
// A hook to be fired when logging on the logging levels returned from // A hook to be fired when logging on the logging levels returned from
// `Levels()` on your implementation of the interface. Note that this is not // `Levels()` on your implementation of the interface. Note that this is not
// fired in a goroutine or a channel with workers, you should handle such // fired in a goroutine or a channel with workers, you should handle such
@ -24,11 +28,13 @@ func (hooks LevelHooks) Add(hook Hook) {
// Fire all the hooks for the passed level. Used by `entry.log` to fire // Fire all the hooks for the passed level. Used by `entry.log` to fire
// appropriate hooks for a log entry. // appropriate hooks for a log entry.
func (hooks LevelHooks) Fire(level Level, entry *Entry) error { func (hooks LevelHooks) Fire(level Level, entry *Entry) error {
var aggErr error
for _, hook := range hooks[level] { for _, hook := range hooks[level] {
if err := hook.Fire(entry); err != nil { if err := hook.Fire(entry); err != nil {
return err aggErr = fmt.Errorf("%s | %s", aggErr, err)
} }
} }
return nil return aggErr
} }