Skip to content

Commit

Permalink
fix: handle any type that implements error interface
Browse files Browse the repository at this point in the history
  • Loading branch information
sethyates committed Nov 16, 2023
1 parent 2027ee7 commit d746907
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
19 changes: 11 additions & 8 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ const (
ansiBrightRedFaint = "\033[91;2m"
)

const errKey = "err"
const (
errKey = "err"
badKey = "!BADKEY"
)

var (
defaultLevel = slog.LevelInfo
Expand Down Expand Up @@ -345,7 +348,7 @@ func (h *handler) appendAttr(buf *buffer, attr slog.Attr, groupsPrefix string, g
}
} else if err, ok := attr.Value.Any().(tintError); ok {
// append tintError
h.appendTintError(buf, err, groupsPrefix)
h.appendTintError(buf, err, attr.Key, groupsPrefix)
buf.WriteByte(' ')
} else {
h.appendKey(buf, attr.Key, groupsPrefix)
Expand Down Expand Up @@ -395,9 +398,12 @@ func (h *handler) appendValue(buf *buffer, v slog.Value, quote bool) {
}
}

func (h *handler) appendTintError(buf *buffer, err error, groupsPrefix string) {
func (h *handler) appendTintError(buf *buffer, err error, key string, groupsPrefix string) {
if key == badKey {
key = errKey
}
buf.WriteStringIf(!h.noColor, ansiBrightRedFaint)
appendString(buf, groupsPrefix+errKey, true)
appendString(buf, groupsPrefix+key, true)
buf.WriteByte('=')
buf.WriteStringIf(!h.noColor, ansiResetFaint)
appendString(buf, err.Error(), true)
Expand All @@ -424,15 +430,12 @@ func needsQuoting(s string) bool {
return false
}

type tintError struct{ error }
type tintError interface{ Error() string }

// Err returns a tinted (colorized) [slog.Attr] that will be written in red color
// by the [tint.Handler]. When used with any other [slog.Handler], it behaves as
//
// slog.Any("err", err)
func Err(err error) slog.Attr {
if err != nil {
err = tintError{err}
}
return slog.Any(errKey, err)
}
12 changes: 8 additions & 4 deletions handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func Example() {
slog.Info("Starting server", "addr", ":8080", "env", "production")
slog.Debug("Connected to DB", "db", "myapp", "host", "localhost:5432")
slog.Warn("Slow request", "method", "GET", "path", "/users", "duration", 497*time.Millisecond)
slog.Error("DB connection lost", tint.Err(errors.New("connection reset")), "db", "myapp")
slog.Error("DB connection lost", errors.New("connection reset"), "db", "myapp")
// Output:
}

Expand All @@ -52,13 +52,13 @@ func TestHandler(t *testing.T) {
},
{
F: func(l *slog.Logger) {
l.Error("test", tint.Err(errors.New("fail")))
l.Error("test", errors.New("fail"))
},
Want: `Nov 10 23:00:00.000 ERR test err=fail`,
},
{
F: func(l *slog.Logger) {
l.Info("test", slog.Group("group", slog.String("key", "val"), tint.Err(errors.New("fail"))))
l.Info("test", slog.Group("group", slog.String("key", "val"), errors.New("fail")))
},
Want: `Nov 10 23:00:00.000 INF test group.key=val group.err=fail`,
},
Expand Down Expand Up @@ -331,7 +331,7 @@ func TestHandler(t *testing.T) {
{ // https://github.com/lmittmann/tint/issues/44
F: func(l *slog.Logger) {
l = l.WithGroup("group")
l.Error("test", tint.Err(errTest))
l.Error("test", errTest)
},
Want: `Nov 10 23:00:00.000 ERR test group.err=fail`,
},
Expand Down Expand Up @@ -401,6 +401,10 @@ func TestReplaceAttr(t *testing.T) {

replaceAttrRecorder := func(record *[]replaceAttrParams) func([]string, slog.Attr) slog.Attr {
return func(groups []string, a slog.Attr) slog.Attr {
// Ignore time since it will be necessarily different when logged at different times
if a.Key == "time" {
return slog.Attr{}
}
*record = append(*record, replaceAttrParams{groups, a})
return a
}
Expand Down

0 comments on commit d746907

Please sign in to comment.