Return sink write errors from every handler (closes #22)
The console and JSON handlers threw away the error from their write to stdout, so a lost log line looked delivered. They now return it, wrapped. The webhook handler also returns an error for a status outside 2xx. The multiplex handler passes the record to every handler and returns their errors joined with errors.Join instead of stopping at the first. Both stdout handlers gain an unexported writer, nil meaning os.Stdout at write time, so tests can supply a sink that fails. The README says what each handler returns and that the slog.Logger methods discard a handler's error. Model: opus-5-5
This commit is contained in:
+12
-1
@@ -4,12 +4,17 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// errWebhookStatus is returned when the webhook answers with a status
|
||||
// outside 2xx.
|
||||
var errWebhookStatus = errors.New("webhook did not accept the record")
|
||||
|
||||
// WebhookHandler POSTs each log record as JSON to a configured webhook
|
||||
// URL.
|
||||
type WebhookHandler struct {
|
||||
@@ -61,7 +66,8 @@ func (w *WebhookHandler) WithGroup(name string) slog.Handler {
|
||||
}
|
||||
|
||||
// Handle marshals the record, with its attributes, to one JSON object and
|
||||
// POSTs it to the webhook URL.
|
||||
// POSTs it to the webhook URL. It returns an error when the request fails
|
||||
// or the server answers with a status outside 2xx.
|
||||
func (w *WebhookHandler) Handle(ctx context.Context, record slog.Record) error {
|
||||
jsonData, err := json.Marshal(recordToMap(record, w.attrs))
|
||||
if err != nil {
|
||||
@@ -87,5 +93,10 @@ func (w *WebhookHandler) Handle(ctx context.Context, record slog.Record) error {
|
||||
|
||||
defer func() { _ = response.Body.Close() }()
|
||||
|
||||
if response.StatusCode < http.StatusOK ||
|
||||
response.StatusCode >= http.StatusMultipleChoices {
|
||||
return fmt.Errorf("%w: %s", errWebhookStatus, response.Status)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user