- internal/logging: LOG_LEVEL/LOG_FORMAT parsing and slog handler - request_id middleware (X-Request-ID or generated, echoed) + debug access log - httpx registers errors; middleware logs internal causes with request_id - health excluded, objects/sse debug-only, no query/body/secrets in logs - new observability capability spec; README/.env.example docs
69 lines
1.8 KiB
Go
69 lines
1.8 KiB
Go
package httpx
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func runHandler(t *testing.T, handler gin.HandlerFunc) (*gin.Context, *httptest.ResponseRecorder) {
|
|
t.Helper()
|
|
gin.SetMode(gin.TestMode)
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = httptest.NewRequest(http.MethodGet, "/", nil)
|
|
handler(c)
|
|
return c, w
|
|
}
|
|
|
|
func TestRespondErrorRegistersInternalError(t *testing.T) {
|
|
c, w := runHandler(t, func(c *gin.Context) {
|
|
RespondError(c, errors.New("boom"))
|
|
})
|
|
if len(c.Errors) != 1 {
|
|
t.Fatalf("c.Errors = %d, want 1", len(c.Errors))
|
|
}
|
|
if w.Code != http.StatusInternalServerError {
|
|
t.Fatalf("status = %d, want 500", w.Code)
|
|
}
|
|
if body := w.Body.String(); body != `{"error":{"code":"internal_error","message":"internal server error"}}` {
|
|
t.Fatalf("body = %s", body)
|
|
}
|
|
}
|
|
|
|
func TestRespondErrorRegistersAppError(t *testing.T) {
|
|
c, w := runHandler(t, func(c *gin.Context) {
|
|
RespondError(c, NotFound("photo_not_found", "photo not found"))
|
|
})
|
|
if len(c.Errors) != 1 {
|
|
t.Fatalf("c.Errors = %d, want 1", len(c.Errors))
|
|
}
|
|
if w.Code != http.StatusNotFound {
|
|
t.Fatalf("status = %d, want 404", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestAbortRegistersInternalError(t *testing.T) {
|
|
c, w := runHandler(t, func(c *gin.Context) {
|
|
Abort(c, errors.New("kaboom"))
|
|
})
|
|
if len(c.Errors) != 1 {
|
|
t.Fatalf("c.Errors = %d, want 1", len(c.Errors))
|
|
}
|
|
if w.Code != http.StatusInternalServerError {
|
|
t.Fatalf("status = %d, want 500", w.Code)
|
|
}
|
|
}
|
|
|
|
// Ensure the package-level recovery of AppError still works for logging levels.
|
|
func TestInternalIsAppError500(t *testing.T) {
|
|
err := Internal("oops")
|
|
var appErr *AppError
|
|
if !errors.As(err, &appErr) || appErr.Status != http.StatusInternalServerError {
|
|
t.Fatalf("Internal() = %#v", err)
|
|
}
|
|
}
|