feat(api): attach request meta to error envelopes
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
c48effb6b7
commit
1ec5bf4062
2 changed files with 52 additions and 3 deletions
|
|
@ -73,6 +73,17 @@ func (g autoResponseMetaTestGroup) RegisterRoutes(rg *gin.RouterGroup) {
|
|||
})
|
||||
}
|
||||
|
||||
type autoErrorResponseMetaTestGroup struct{}
|
||||
|
||||
func (g autoErrorResponseMetaTestGroup) Name() string { return "auto-error-response-meta" }
|
||||
func (g autoErrorResponseMetaTestGroup) BasePath() string { return "/v1" }
|
||||
func (g autoErrorResponseMetaTestGroup) RegisterRoutes(rg *gin.RouterGroup) {
|
||||
rg.GET("/error", func(c *gin.Context) {
|
||||
time.Sleep(2 * time.Millisecond)
|
||||
c.JSON(http.StatusBadRequest, api.Fail("bad_request", "request failed"))
|
||||
})
|
||||
}
|
||||
|
||||
// ── Bearer auth ─────────────────────────────────────────────────────────
|
||||
|
||||
func TestBearerAuth_Bad_MissingToken(t *testing.T) {
|
||||
|
|
@ -310,6 +321,42 @@ func TestResponseMeta_Good_AttachesMetaAutomatically(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestResponseMeta_Good_AttachesMetaToErrorResponses(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
e, _ := api.New(
|
||||
api.WithRequestID(),
|
||||
api.WithResponseMeta(),
|
||||
)
|
||||
e.Register(autoErrorResponseMetaTestGroup{})
|
||||
|
||||
h := e.Handler()
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(http.MethodGet, "/v1/error", nil)
|
||||
req.Header.Set("X-Request-ID", "client-id-auto-error-meta")
|
||||
h.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Fatalf("expected 400, got %d", w.Code)
|
||||
}
|
||||
|
||||
var resp api.Response[string]
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("unmarshal error: %v", err)
|
||||
}
|
||||
if resp.Meta == nil {
|
||||
t.Fatal("expected Meta to be present")
|
||||
}
|
||||
if resp.Meta.RequestID != "client-id-auto-error-meta" {
|
||||
t.Fatalf("expected request_id=%q, got %q", "client-id-auto-error-meta", resp.Meta.RequestID)
|
||||
}
|
||||
if resp.Meta.Duration == "" {
|
||||
t.Fatal("expected duration to be populated")
|
||||
}
|
||||
if resp.Error == nil || resp.Error.Code != "bad_request" {
|
||||
t.Fatalf("expected bad_request error, got %+v", resp.Error)
|
||||
}
|
||||
}
|
||||
|
||||
// ── CORS ────────────────────────────────────────────────────────────────
|
||||
|
||||
func TestCORS_Good_PreflightAllOrigins(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -104,8 +104,8 @@ func (w *responseMetaRecorder) commit() {
|
|||
_, _ = w.ResponseWriter.Write(w.body.Bytes())
|
||||
}
|
||||
|
||||
// responseMetaMiddleware injects request metadata into successful JSON
|
||||
// envelope responses before they are written to the client.
|
||||
// responseMetaMiddleware injects request metadata into JSON envelope
|
||||
// responses before they are written to the client.
|
||||
func responseMetaMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if _, ok := c.Get(requestStartContextKey); !ok {
|
||||
|
|
@ -156,7 +156,9 @@ func refreshResponseMetaBody(body []byte, meta *Meta) []byte {
|
|||
}
|
||||
|
||||
if _, ok := obj["success"]; !ok {
|
||||
return body
|
||||
if _, ok := obj["error"]; !ok {
|
||||
return body
|
||||
}
|
||||
}
|
||||
|
||||
current := map[string]any{}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue