From 994afe82506c1dc7781ef0b57c29f7846caf7fa6 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Fri, 6 Mar 2026 14:26:33 -0500 Subject: [PATCH] fix(middleware): improve HTTP status code tracking in request tracing Enhanced the responseWriter wrapper to properly capture HTTP status codes by implementing WriteHeader method and storing status code in the wrapper struct. This ensures accurate status logging in request traces. Changes: - Added status field to responseWriter struct to track HTTP status codes - Implemented WriteHeader method to capture status when written - Added Hijack method pass-through for WebSocket/upgrade support - Updated request logging to use captured status from recorder instead of accessing Echo's internal Response object This fix addresses potential issues where status codes were not being properly captured in request logs, particularly for error responses and non-2xx status codes. --- internal/middleware/request_tracing.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/internal/middleware/request_tracing.go b/internal/middleware/request_tracing.go index 4eb5718..343fd36 100644 --- a/internal/middleware/request_tracing.go +++ b/internal/middleware/request_tracing.go @@ -2,10 +2,12 @@ package middleware import ( "bookhoard/internal/config" + "bufio" "bytes" "encoding/json" "io" "log" + "net" "net/http" "time" @@ -15,9 +17,21 @@ import ( type responseWriter struct { http.ResponseWriter - size int + size int + status int } +func (r *responseWriter) WriteHeader(statusCode int) { + r.status = statusCode + r.ResponseWriter.WriteHeader(statusCode) +} +func (r *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + // Pass through Hijacker if underlying writer supports it + if hj, ok := r.ResponseWriter.(http.Hijacker); ok { + return hj.Hijack() + } + return nil, nil, http.ErrNotSupported +} func (r *responseWriter) Write(b []byte) (int, error) { size, err := r.ResponseWriter.Write(b) r.size += size @@ -105,7 +119,7 @@ func RequestTracingMiddleware(cfg *config.Config) echo.MiddlewareFunc { RemoteAddr: c.RealIP(), UserAgent: c.Request().UserAgent(), Duration: duration, - StatusCode: c.Response().(*echo.Response).Status, + StatusCode: recorder.status, ResponseSize: int64(recorder.size), }