From fa027347d32012678df1dd7aafded6d8e1444c1a Mon Sep 17 00:00:00 2001 From: wjqserver <114663932+WJQSERVER@users.noreply.github.com> Date: Tue, 7 Apr 2026 09:35:39 +0800 Subject: [PATCH] fix: reduce default error response overhead Encode the built-in 404 and 405 payload with a fixed struct instead of a map so default error pages allocate less on the hot miss path. Add a regression test to keep the JSON shape stable. --- engine.go | 12 +++++++----- engine_test.go | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/engine.go b/engine.go index 698fbd5..81d3673 100644 --- a/engine.go +++ b/engine.go @@ -126,6 +126,12 @@ type ErrorHandler func(c *Context, code int, err error) var errMethodNotAllowed = errors.New("method not allowed") var errNotFound = errors.New("not found") +type defaultErrorResponse struct { + Code int `json:"code"` + Message string `json:"message"` + Error string `json:"error"` +} + var methodNotAllowedHandler HandlerFunc = func(c *Context) { httpMethod := c.Request.Method requestPath := routeLookupPath(c.Request) @@ -187,11 +193,7 @@ func defaultErrorHandle(c *Context, code int, err error) { // 检查客户端是 if err != nil { errMsg = err.Error() } - c.JSON(code, H{ - "code": code, - "message": http.StatusText(code), - "error": errMsg, - }) + c.JSON(code, defaultErrorResponse{Code: code, Message: http.StatusText(code), Error: errMsg}) c.Writer.Flush() c.Abort() return diff --git a/engine_test.go b/engine_test.go index 292d5e2..71f9772 100644 --- a/engine_test.go +++ b/engine_test.go @@ -1,6 +1,7 @@ package touka import ( + "encoding/json" "net/http" "testing" ) @@ -100,3 +101,23 @@ func TestOptionsAllowHeaderListsMatchingMethods(t *testing.T) { t.Fatalf("expected Allow header to list matching methods, got %q", allow) } } + +func TestDefaultErrorHandleJSONShape(t *testing.T) { + engine := New() + rr := PerformRequest(engine, http.MethodGet, "/missing", nil, nil) + if rr.Code != http.StatusNotFound { + t.Fatalf("expected status %d, got %d", http.StatusNotFound, rr.Code) + } + + var body struct { + Code int `json:"code"` + Message string `json:"message"` + Error string `json:"error"` + } + if err := json.Unmarshal(rr.Body.Bytes(), &body); err != nil { + t.Fatalf("expected JSON error body, got %q: %v", rr.Body.String(), err) + } + if body.Code != http.StatusNotFound || body.Message != http.StatusText(http.StatusNotFound) || body.Error != "not found" { + t.Fatalf("unexpected error payload: %+v", body) + } +}