You've already forked agentic-coding-workflow
feat(http): chi router skeleton + Google-style error response
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
// Package httpx provides the HTTP transport layer: a Chi-based router
|
||||
// skeleton and Google API style JSON response helpers (WriteJSON,
|
||||
// WriteError). It deliberately uses package name "httpx" to avoid
|
||||
// shadowing the standard library "net/http" package at call sites.
|
||||
package httpx
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/yan1h/agent-coding-workflow/internal/infra/errs"
|
||||
)
|
||||
|
||||
// WriteJSON writes body as JSON with the given HTTP status. The
|
||||
// Content-Type header is set to application/json before WriteHeader is
|
||||
// called. Encode errors are intentionally ignored: by the time the
|
||||
// status has been written the connection is committed, and the caller
|
||||
// has no meaningful recovery path.
|
||||
func WriteJSON(w http.ResponseWriter, status int, body any) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(status)
|
||||
_ = json.NewEncoder(w).Encode(body)
|
||||
}
|
||||
|
||||
// errorResponse is the Google API style flat error body.
|
||||
type errorResponse struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Fields map[string]any `json:"fields,omitempty"`
|
||||
RequestID string `json:"request_id,omitempty"`
|
||||
}
|
||||
|
||||
// WriteError translates err into a JSON error response. *errs.AppError
|
||||
// values are rendered with their declared Code/Message/Fields and the
|
||||
// HTTP status mapped via errs.HTTPStatus. Any other error is reported
|
||||
// as a generic 500 internal error so internal details don't leak.
|
||||
func WriteError(w http.ResponseWriter, requestID string, err error) {
|
||||
if ae, ok := errs.As(err); ok {
|
||||
WriteJSON(w, errs.HTTPStatus(ae.Code), errorResponse{
|
||||
Code: string(ae.Code),
|
||||
Message: ae.Message,
|
||||
Fields: ae.Fields,
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
WriteJSON(w, http.StatusInternalServerError, errorResponse{
|
||||
Code: string(errs.CodeInternal),
|
||||
Message: "internal server error",
|
||||
RequestID: requestID,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user