diff --git a/cloudslog/errors.go b/cloudslog/errors.go new file mode 100644 index 0000000..8522314 --- /dev/null +++ b/cloudslog/errors.go @@ -0,0 +1,24 @@ +package cloudslog + +import ( + "encoding/json" + "log/slog" +) + +// Errors creates a slog attribute for a list of errors. +// unlike slog.Any, this will render the error strings when using slog.JSONHandler. +func Errors(errors []error) slog.Attr { + jsonErrors := make([]error, len(errors)) + for i, err := range errors { + jsonErrors[i] = &jsonError{error: err} + } + return slog.Any("errors", jsonErrors) +} + +type jsonError struct { + error +} + +func (j jsonError) MarshalJSON() ([]byte, error) { + return json.Marshal(j.error.Error()) +} diff --git a/cloudslog/errors_test.go b/cloudslog/errors_test.go new file mode 100644 index 0000000..d525423 --- /dev/null +++ b/cloudslog/errors_test.go @@ -0,0 +1,20 @@ +package cloudslog + +import ( + "errors" + "log/slog" + "strings" + "testing" + + "gotest.tools/v3/assert" +) + +func TestErrors(t *testing.T) { + t.Run("errors", func(t *testing.T) { + var b strings.Builder + logger := slog.New(newHandler(&b, LoggerConfig{})) + + logger.Info("test", Errors([]error{errors.New("test_error")})) + assert.Assert(t, strings.Contains(b.String(), "test_error")) + }) +}