textmachine/platform/internal/httpapi/problem.go

35 lines
1.2 KiB
Go

package httpapi
import (
"encoding/json"
"log/slog"
"net/http"
)
// Problem is an RFC 9457 error body.
//
// Detail NEVER carries engine text. The engine's own detail strings read like "CJK leak in the ru
// output: 第一节" — pipeline vocabulary that must not cross this seam (contract §2.12). What goes
// here is a product phrase or nothing.
type Problem struct {
Type string `json:"type"`
Title string `json:"title"`
Status int `json:"status"`
Detail string `json:"detail,omitempty"`
}
// WriteProblem renders an error response.
func WriteProblem(w http.ResponseWriter, status int, title, detail string) {
w.Header().Set("Content-Type", "application/problem+json")
w.WriteHeader(status)
if err := json.NewEncoder(w).Encode(Problem{Type: "about:blank", Title: title, Status: status, Detail: detail}); err != nil {
slog.Debug("problem body not delivered", "err", err) // the client went away mid-write
}
}
// ProblemHandler is a static problem response, for the middleware that must be handed a denier.
func ProblemHandler(status int, title string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
WriteProblem(w, status, title, "")
})
}