package http import ( "encoding/json" "net/http" "github.com/go-chi/chi/v5/middleware" ) type ResponseErr struct { Message string `json:"message"` Trace string `json:"trace"` Details map[string]any `json:"details"` } type ResponseErrReadyToSend interface { Send(http.ResponseWriter) error } type ResponseErrBuilder interface { WithDetails(map[string]any) ResponseErrBuilder WithMessage(string) ResponseErrBuilder WithStatusCode(int) ResponseErrBuilder WithTrace(string) ResponseErrBuilder Ready() ResponseErrReadyToSend Send(http.ResponseWriter, *http.Request) error } type responseErrBuilder struct { details map[string]any message string status int trace string ready *ResponseErr } type readyResponseErr struct { builder responseErrBuilder } func (r readyResponseErr) Send(response http.ResponseWriter) error { format, err := json.Marshal(r.builder.ready) if err != nil { return err } if r.builder.status == 0 { r.builder.status = http.StatusInternalServerError } response.WriteHeader(r.builder.status) _, err = response.Write(format) return err } func (r responseErrBuilder) WithTrace(s string) ResponseErrBuilder { r.trace = s return r } func (r responseErrBuilder) WithStatusCode(i int) ResponseErrBuilder { r.status = i return r } func NewResponseErrBuilder() ResponseErrBuilder { return &responseErrBuilder{} } func (r responseErrBuilder) WithDetails(m map[string]any) ResponseErrBuilder { r.details = m return r } func (r responseErrBuilder) WithMessage(s string) ResponseErrBuilder { r.message = s return r } func (r responseErrBuilder) Ready() ResponseErrReadyToSend { r.ready = &ResponseErr{ Message: r.message, Trace: r.trace, Details: r.details, } return readyResponseErr{ builder: r, } } func (r responseErrBuilder) Send(response http.ResponseWriter, request *http.Request) error { if r.ready == nil { r.ready = &ResponseErr{ Message: r.message, Trace: middleware.GetReqID(request.Context()), Details: r.details, } } format, err := json.Marshal(r.ready) if err != nil { return err } if r.status == 0 { r.status = http.StatusInternalServerError } response.Header().Set("Content-Type", "application/json") response.WriteHeader(r.status) _, err = response.Write(format) return err }