Files
weichen f3f23a3018 feat(errcode): 用稳定错误码记录 HTTP 与异步失败
失败响应此前不写日志,request_id 无法对照原因。注册表不覆盖处理器已经给出的 HTTP 状态。
2026-09-28 02:27:16 +00:00

92 lines
2.8 KiB
Go

package server
import (
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"testing"
"chat-agent-system/internal/docgov"
"chat-agent-system/internal/projectworkflow"
)
func TestDomainHTTPStatus_MapsKnownSentinels(t *testing.T) {
cases := []struct {
err error
status int
ok bool
}{
{nil, 0, false},
{errors.New("other"), 0, false},
{docgov.ErrDocumentBusy, http.StatusConflict, true},
{&docgov.DocumentBusyError{DocID: "d1"}, http.StatusConflict, true},
{docgov.ErrDocumentLocked, http.StatusConflict, true},
{docgov.ErrForceEditNotAllowed, http.StatusConflict, true},
{docgov.ErrLeaseNotHeld, http.StatusConflict, true},
{docgov.ErrLeaseExpired, http.StatusConflict, true},
{docgov.ErrDocumentNotFound, http.StatusNotFound, true},
{docgov.ErrProposalNotFound, http.StatusNotFound, true},
{docgov.ErrUnauthorizedActor, http.StatusForbidden, true},
{docgov.ErrOnlyAuthorCanEdit, http.StatusForbidden, true},
{docgov.ErrReviewerCannotEdit, http.StatusForbidden, true},
{docgov.ErrApproverCannotEdit, http.StatusForbidden, true},
{projectworkflow.ErrPrerequisiteNotMet, http.StatusBadRequest, true},
{&docgov.ContentError{Code: docgov.ErrCodeDocumentNotFound}, http.StatusNotFound, true},
{&docgov.ContentError{Code: docgov.ErrCodeProjectionMissing}, http.StatusConflict, true},
}
for _, tc := range cases {
got, ok := domainHTTPStatus(tc.err)
if ok != tc.ok || got != tc.status {
t.Fatalf("%v: got status=%d ok=%v want status=%d ok=%v", tc.err, got, ok, tc.status, tc.ok)
}
}
}
func TestWriteDocGovError_UsesAdapterStatuses(t *testing.T) {
rec := httptest.NewRecorder()
writeDocGovError(rec, nil, docgov.ErrProposalNotFound)
if rec.Code != http.StatusNotFound {
t.Fatalf("status %d", rec.Code)
}
rec = httptest.NewRecorder()
writeDocGovError(rec, nil, docgov.ErrUnauthorizedActor)
if rec.Code != http.StatusForbidden {
t.Fatalf("status %d", rec.Code)
}
rec = httptest.NewRecorder()
writeDocGovError(rec, nil, docgov.ErrOnlyAuthorCanEdit)
if rec.Code != http.StatusForbidden {
t.Fatalf("OnlyAuthorCanEdit status %d", rec.Code)
}
rec = httptest.NewRecorder()
writeDocGovError(rec, nil, &docgov.DocumentBusyError{DocID: "d", Reason: "held"})
if rec.Code != http.StatusConflict {
t.Fatalf("status %d", rec.Code)
}
var body map[string]any
if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil {
t.Fatal(err)
}
if body["error"] != "document_busy" {
t.Fatalf("body=%v", body)
}
}
func TestWriteTaskError_DefaultsTo500(t *testing.T) {
rec := httptest.NewRecorder()
writeTaskError(rec, nil, errors.New("boom"), nil)
if rec.Code != http.StatusInternalServerError {
t.Fatalf("status %d", rec.Code)
}
rec = httptest.NewRecorder()
writeTaskError(rec, nil, docgov.ErrDocumentBusy, map[string]string{"ok": "no"})
if rec.Code != http.StatusConflict {
t.Fatalf("status %d", rec.Code)
}
}