Files
Error-Code-System/httpx/httpx_test.go
T
weichenandCursor bd53e9ba79
ci / vet-and-test (push) Successful in 3s
ci / docker-checkout-hostgateway (push) Successful in 3s
Add a shared error-code catalog so failures can be traced by stable codes.
Services can resolve legacy aliases and expose the catalog over CLI and HTTP instead of ad-hoc error strings.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-29 13:43:12 +00:00

87 lines
2.6 KiB
Go

package httpx
import (
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"testing"
"error-code-system/domains"
"error-code-system/errcode"
)
func TestTraceGeneratesAndEchoes(t *testing.T) {
var seen string
h := Trace(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
seen = TraceID(r)
w.WriteHeader(http.StatusNoContent)
}))
req := httptest.NewRequest(http.MethodGet, "/", nil)
rec := httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Header().Get(TraceHeader) == "" || seen != rec.Header().Get(TraceHeader) {
t.Fatalf("generated trace header=%q seen=%q", rec.Header().Get(TraceHeader), seen)
}
req = httptest.NewRequest(http.MethodGet, "/", nil)
req.Header.Set(TraceHeader, "trace-from-caller")
rec = httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Header().Get(TraceHeader) != "trace-from-caller" {
t.Fatalf("echo = %s", rec.Header().Get(TraceHeader))
}
req = httptest.NewRequest(http.MethodGet, "/", nil)
req.Header.Set(TraceHeader, "bad id")
rec = httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Header().Get(TraceHeader) == "bad id" || rec.Header().Get(TraceHeader) == "" {
t.Fatal("invalid trace should be replaced")
}
}
func TestWriteErrorEnvelope(t *testing.T) {
reg := errcode.NewRegistry()
domains.RegisterAll(reg)
req := httptest.NewRequest(http.MethodGet, "/", nil)
req.Header.Set(TraceHeader, "trace-abc-1234")
rec := httptest.NewRecorder()
err := errcode.Wrap(errors.New("dial timeout"), errcode.AgentProviderUnavailable, "模型不可达", "model", "glm-4")
WriteError(reg, rec, req, err)
if rec.Code != http.StatusServiceUnavailable {
t.Fatalf("status %d", rec.Code)
}
var env Envelope
if err := json.Unmarshal(rec.Body.Bytes(), &env); err != nil {
t.Fatal(err)
}
if env.Error.Code != string(errcode.AgentProviderUnavailable) || env.Error.Message == "" {
t.Fatalf("body %+v", env.Error)
}
if env.Error.Reason != "模型不可达" || env.Error.TraceID != "trace-abc-1234" {
t.Fatalf("body %+v", env.Error)
}
if rec.Header().Get(TraceHeader) != "trace-abc-1234" {
t.Fatal("trace header not echoed")
}
}
func TestWriteErrorUnknownFallsBack(t *testing.T) {
reg := errcode.NewRegistry()
domains.RegisterAll(reg)
rec := httptest.NewRecorder()
WriteError(reg, rec, httptest.NewRequest(http.MethodGet, "/", nil), errcode.New("no.such_code", "x"))
if rec.Code != http.StatusInternalServerError {
t.Fatalf("status %d body %s", rec.Code, rec.Body.String())
}
var env Envelope
if err := json.Unmarshal(rec.Body.Bytes(), &env); err != nil {
t.Fatal(err)
}
if env.Error.Code != string(errcode.SysUnknownCode) {
t.Fatalf("code %s", env.Error.Code)
}
}