Documentation
¶
Overview ¶
Package response provides HTTP response and error handling for requestCore.
Safe error response (for consuming repos):
- Do not put string(rawResp) or full upstream response bodies in libError descriptions; use size/status/hash and log details separately (see libCallApi).
- Do not use %+v on whole response structs in error messages that can become client-visible.
- Use only codes from a fixed catalog and ensure they are seeded/localized (e.g. SystemFault, API_*); avoid dynamic values as public error codes.
Index ¶
- Constants
- Variables
- func GetDescFromCode(code string, _ any, errDescList map[string]string) (string, string)
- func GetStack(skip int, exclude string) string
- func JustPrintResp(respBytes []byte, _ string, status int) (int, map[string]string, any, error)
- func LastHTTPStatus(w webFramework.WebFramework) int
- func ParseRemoteRespJSON(respBytes []byte, _ string, status int) (int, map[string]string, any, error)
- func ParseWsRemoteResp(respBytes []byte, _ string, status int) (int, map[string]string, any, error)
- func SanitizeForClient(candidate any, maxLen int) string
- type DbResponse
- type ErrorData
- func (e ErrorData) Child(err ErrorState) ErrorState
- func (e ErrorData) ChildErr(err error) ErrorState
- func (e ErrorData) Error() string
- func (e ErrorData) Format(header string, stack *strings.Builder)
- func (e ErrorData) GetDescription() string
- func (e ErrorData) GetInput() any
- func (e ErrorData) GetMessage() any
- func (e ErrorData) GetStatus() int
- func (e *ErrorData) Input(in any) ErrorState
- func (e ErrorData) LogValue() slog.Value
- func (e ErrorData) SetDescription(desc string) ErrorState
- func (e ErrorData) SetMessage(msg any) ErrorState
- func (e ErrorData) SetStatus(status int) ErrorState
- func (e ErrorData) WsResponse() string
- type ErrorResponse
- type ErrorState
- type FileResponse
- type Problem
- func (p *Problem) Error() string
- func (p *Problem) MarshalJSON() ([]byte, error)
- func (p *Problem) Unwrap() error
- func (p *Problem) WithCause(err error) *Problem
- func (p *Problem) WithCode(code string) *Problem
- func (p *Problem) WithDetail(detail string) *Problem
- func (p *Problem) WithInstance(instance string) *Problem
- func (p *Problem) WithRequestID(id string) *Problem
- func (p *Problem) WithTraceID(id string) *Problem
- func (p *Problem) WriteTo(rw http.ResponseWriter) error
- func (p *Problem) WriteToWebFramework(w webFramework.WebFramework) error
- type ProblemMapper
- type ProblemMapperRegistry
- func (r *ProblemMapperRegistry) Freeze()
- func (r *ProblemMapperRegistry) Frozen() bool
- func (r *ProblemMapperRegistry) Map(err error) *Problem
- func (r *ProblemMapperRegistry) Register(matcher ProblemMatcher, mapper ProblemMapper) error
- func (r *ProblemMapperRegistry) SetFallback(mapper ProblemMapper) error
- type ProblemMatcher
- type ProblemViolation
- type Receipt
- type RespData
- type RespType
- type ResponseHandler
- type StatusAwareResponder
- type WebHanlder
- func (m WebHanlder) Error(w webFramework.WebFramework, err error)
- func (m WebHanlder) GetErrorsArray(message string, data any) []ErrorResponse
- func (m WebHanlder) OK(w webFramework.WebFramework, resp any)
- func (m WebHanlder) OKWithAttachment(w webFramework.WebFramework, attachment *FileResponse)
- func (m WebHanlder) OKWithReceipt(w webFramework.WebFramework, resp any, receipt *Receipt)
- func (m WebHanlder) OKWithStatus(w webFramework.WebFramework, status int, resp any)
- func (m WebHanlder) OKWithStatusAndHeaders(w webFramework.WebFramework, status int, headers map[string]string, resp any)
- func (m WebHanlder) Respond(code, status int, message string, data any, abort bool, ...)
- func (m WebHanlder) RespondWithAttachment(code, status int, message string, file *FileResponse, abort bool, ...)
- func (m WebHanlder) RespondWithReceipt(code, status int, message string, data any, printData *Receipt, abort bool, ...)
- type WsRemoteResponse
- type WsResponse
Constants ¶
const ( // NoDataFound is the error code for missing data. NoDataFound = "NO-DATA-FOUND" // SystemFault is the error code for internal system faults. SystemFault = "SYSTEM_FAULT" // SystemFaultDesc is the default localized description for system faults. SystemFaultDesc = "خطای سیستمی" )
const LastHTTPStatusLocal = "response.http_status"
LastHTTPStatusLocal is the local-storage key for the most recent HTTP status code.
const MaxDescriptionLength = 512
MaxDescriptionLength is the maximum length of error description sent to API clients.
const ProblemContentType = "application/problem+json"
ProblemContentType is the media type for RFC 9457 problem details.
Variables ¶
var ErrProblemRegistryFrozen = errors.New("response: problem mapper registry is frozen")
ErrProblemRegistryFrozen is returned when attempting to register or modify a frozen ProblemMapperRegistry.
Functions ¶
func GetDescFromCode ¶ added in v0.3.21
GetDescFromCode returns (code, description) for API response. When code is not in errDescList, it returns a safe fallback (SystemFault + localized text) and never exposes raw data.
func GetStack ¶ added in v0.9.40
GetStack returns a formatted caller stack frame, skipping framework-internal files.
func JustPrintResp ¶
JustPrintResp unmarshals and logs a remote response without returning parsed data.
func LastHTTPStatus ¶ added in v0.26.0
func LastHTTPStatus(w webFramework.WebFramework) int
LastHTTPStatus returns the HTTP status code recorded by the most recent respond call.
func ParseRemoteRespJSON ¶ added in v0.28.1
func ParseRemoteRespJSON(respBytes []byte, _ string, status int) (int, map[string]string, any, error)
ParseRemoteRespJSON parses a remote JSON response and extracts status, error details, and result.
func ParseWsRemoteResp ¶
ParseWsRemoteResp parses a remote JSON response and returns the full WsRemoteResponse on success.
func SanitizeForClient ¶ added in v0.22.6
SanitizeForClient turns a candidate description into a safe string for API output. - If candidate is a string: trims, applies max length, and optionally redacts sensitive patterns. - If candidate is not a string (map, struct, etc.): returns SystemFaultDesc without dumping the value.
Types ¶
type DbResponse ¶
type DbResponse struct {
Status int `json:"status"`
Description string `json:"description"`
Result any `json:"result"`
ErrorCode string `json:"error_code,omitempty"`
}
DbResponse represents the standard structure of a database query response.
type ErrorData ¶ added in v0.9.5
type ErrorData struct {
Status int
Description string
Message any
// contains filtered or unexported fields
}
ErrorData holds structured error information including status, description, message, and child errors.
func (ErrorData) Child ¶ added in v0.9.5
func (e ErrorData) Child(err ErrorState) ErrorState
Child appends an ErrorState as a child to this error and returns the updated state.
func (ErrorData) ChildErr ¶ added in v0.9.5
func (e ErrorData) ChildErr(err error) ErrorState
ChildErr wraps a standard error as a child ErrorState and appends it to the chain.
func (ErrorData) Error ¶ added in v0.9.5
Error returns a formatted multi-line string representation of the error chain.
func (ErrorData) Format ¶ added in v0.9.13
Format writes a structured text representation of the error and its children into the given builder.
func (ErrorData) GetDescription ¶ added in v0.9.5
GetDescription returns the error description string.
func (ErrorData) GetInput ¶ added in v0.9.6
GetInput returns the input data associated with the error.
func (ErrorData) GetMessage ¶ added in v0.9.5
GetMessage returns the error message payload.
func (ErrorData) GetStatus ¶ added in v0.9.5
GetStatus returns the HTTP status code associated with the error.
func (*ErrorData) Input ¶ added in v0.9.5
func (e *ErrorData) Input(in any) ErrorState
Input associates input data with the error and returns the updated ErrorState.
func (ErrorData) LogValue ¶ added in v0.15.0
LogValue implements slog.LogValuer and returns a grouped value with fields redacted. See https://pkg.go.dev/log/slog#LogValuer
func (ErrorData) SetDescription ¶ added in v0.9.5
func (e ErrorData) SetDescription(desc string) ErrorState
SetDescription sets the error description and returns the updated ErrorState.
func (ErrorData) SetMessage ¶ added in v0.9.5
func (e ErrorData) SetMessage(msg any) ErrorState
SetMessage sets the error message payload and returns the updated ErrorState.
func (ErrorData) SetStatus ¶ added in v0.9.5
func (e ErrorData) SetStatus(status int) ErrorState
SetStatus sets the HTTP status code and returns the updated ErrorState.
func (ErrorData) WsResponse ¶ added in v0.9.5
WsResponse returns a hash-like string combining the error's description, source, input, message, and status.
type ErrorResponse ¶
ErrorResponse represents a single error entry returned to API clients.
func FormatErrorResp ¶
func FormatErrorResp(errs error, trans ut.Translator) []ErrorResponse
FormatErrorResp translates validator validation errors into a slice of ErrorResponse using the given translator.
func GetErrorsArray ¶
func GetErrorsArray(message string, data any) []ErrorResponse
GetErrorsArray builds a slice of ErrorResponse from a message and data, handling pre-built error arrays.
func GetErrorsArrayWithMap ¶
func GetErrorsArrayWithMap(incomingDesc string, data any, errDescList map[string]string) []ErrorResponse
GetErrorsArrayWithMap resolves error codes against a description map to produce localized ErrorResponse entries.
type ErrorState ¶
type ErrorState interface {
Error() string
Input(in any) ErrorState
GetInput() any
WsResponse() string
SetStatus(int) ErrorState
SetDescription(string) ErrorState
SetMessage(any) ErrorState
ChildErr(error) ErrorState
Child(ErrorState) ErrorState
GetStatus() int
GetDescription() string
GetMessage() any
LogValue() slog.Value
}
ErrorState defines the interface for structured error data with chaining and logging support.
func Error ¶
func Error(status int, desc string, message any, err error) ErrorState
Error creates an ErrorState with the given status, description, message, and wrapped error.
func Errors ¶ added in v0.9.12
func Errors(status int, desc string, message any, err ErrorState) ErrorState
Errors creates an ErrorState by chaining an existing ErrorState with a new status and description.
func ToError ¶
func ToError(desc string, message any, err error) ErrorState
ToError creates an ErrorState with an internal-server-error status from the given description, message, and error.
func ToErrorState ¶
func ToErrorState(err error) ErrorState
ToErrorState converts a standard error into an ErrorState with source tracking.
func Unwrap ¶ added in v0.15.0
func Unwrap(err error) (bool, ErrorState)
Unwrap attempts to extract an ErrorState from the given error, returning whether it succeeded.
type FileResponse ¶ added in v0.10.4
FileResponse holds the file name and path for a file-download response.
type Problem ¶ added in v0.29.0
type Problem struct {
// Type is a URI reference identifying the problem type. Defaults to
// "about:blank" per RFC 9457.
Type string `json:"type"`
// Title is a short, human-readable summary of the problem type.
Title string `json:"title"`
// Status is the HTTP status code.
Status int `json:"status"`
// Detail is a human-readable, safe explanation specific to this
// occurrence. Must not leak sensitive data.
Detail string `json:"detail,omitempty"`
// Instance is a URI reference identifying the specific occurrence.
Instance string `json:"instance,omitempty"`
// Code is a stable extension identifying the error code.
Code string `json:"code,omitempty"`
// Violations is an extension listing validation violations.
Violations []ProblemViolation `json:"violations,omitempty"`
// RequestID is an extension carrying the request identifier.
RequestID string `json:"request_id,omitempty"`
// TraceID is an extension carrying the trace identifier.
TraceID string `json:"trace_id,omitempty"`
// contains filtered or unexported fields
}
Problem implements RFC 9457 Problem Details for HTTP APIs. It satisfies the error and Unwrap interfaces.
This is an additive, opt-in facility. The default v1 response path continues to use the legacy WsResponse envelope. Problem is intended for handlers that explicitly opt into RFC 9457 error responses.
Causes are never serialized by default. Unknown errors always become sanitized 500 problems via the mapper registry.
func NewProblem ¶ added in v0.29.0
NewProblem creates a Problem with the given status and title. The Type defaults to "about:blank".
func NewProblemWithCode ¶ added in v0.29.0
NewProblemWithCode creates a Problem with a stable error code extension.
func NewValidationProblem ¶ added in v0.29.0
func NewValidationProblem(status int, title string, violations []ProblemViolation) *Problem
NewValidationProblem creates a Problem with validation violations. The status should typically be 422 (Unprocessable Entity) or 400.
func (*Problem) Error ¶ added in v0.29.0
Error implements the error interface. It returns a string in the format "problem: <title> (<status>)" without exposing the cause.
func (*Problem) MarshalJSON ¶ added in v0.29.0
MarshalJSON serializes the Problem as RFC 9457 JSON. The cause is never included in the output.
func (*Problem) Unwrap ¶ added in v0.29.0
Unwrap returns the underlying cause error, or nil if none was set. This supports errors.Is and errors.As chaining.
func (*Problem) WithCause ¶ added in v0.29.0
WithCause sets the underlying cause error. The cause is never serialized by MarshalJSON. It is accessible via Unwrap for errors.Is/errors.As chaining.
func (*Problem) WithCode ¶ added in v0.29.0
WithCode sets the stable error code extension and returns the problem.
func (*Problem) WithDetail ¶ added in v0.29.0
WithDetail sets the detail and returns the problem for chaining.
func (*Problem) WithInstance ¶ added in v0.29.0
WithInstance sets the instance URI and returns the problem for chaining.
func (*Problem) WithRequestID ¶ added in v0.29.0
WithRequestID sets the request ID extension and returns the problem.
func (*Problem) WithTraceID ¶ added in v0.29.0
WithTraceID sets the trace ID extension and returns the problem.
func (*Problem) WriteTo ¶ added in v0.29.0
func (p *Problem) WriteTo(rw http.ResponseWriter) error
WriteTo writes the Problem as JSON with the correct content type to the given http.ResponseWriter. This is provided for direct net/http integration outside the webFramework lifecycle.
func (*Problem) WriteToWebFramework ¶ added in v0.29.0
func (p *Problem) WriteToWebFramework(w webFramework.WebFramework) error
WriteToWebFramework writes the Problem as JSON with the correct content type through the v1 webFramework. It sets the Content-Type header, records the HTTP status in local storage (consistent with the legacy respond path), and sends the JSON body via the parser.
This is the v1 integration point for opt-in RFC 9457 responses.
type ProblemMapper ¶ added in v0.29.0
ProblemMapper converts an error into an RFC 9457 Problem. Custom mappers return a complete Problem, not raw response bytes, preserving central commit and content type.
If the mapper does not match the error, it should return nil so the registry can try the next mapper or the fallback.
type ProblemMapperRegistry ¶ added in v0.29.0
type ProblemMapperRegistry struct {
// contains filtered or unexported fields
}
ProblemMapperRegistry holds a set of error-to-Problem mappers with matchers. When Map is called, the registry checks each registered matcher in order; the first matching mapper wins. If no mapper matches, the default sanitizer produces a 500 problem.
Unknown errors always become sanitized 500 problems. Causes are never serialized by default.
Once frozen, Register and SetFallback return ErrRegistryFrozen. The registry should be frozen before serving to prevent runtime mutation.
func DefaultProblemMapperRegistry ¶ added in v0.29.0
func DefaultProblemMapperRegistry() *ProblemMapperRegistry
DefaultProblemMapperRegistry returns a registry with the default 500 sanitizer as the fallback, plus built-in mappers for libError.ErrorData and response.ErrorData. This is the standard registry for v1 applications that opt into RFC 9457 error responses.
func NewProblemMapperRegistry ¶ added in v0.29.0
func NewProblemMapperRegistry() *ProblemMapperRegistry
NewProblemMapperRegistry creates an empty ProblemMapperRegistry with a default 500 sanitizer fallback.
func (*ProblemMapperRegistry) Freeze ¶ added in v0.29.0
func (r *ProblemMapperRegistry) Freeze()
Freeze prevents further registration or fallback changes. Called after startup before serving requests.
func (*ProblemMapperRegistry) Frozen ¶ added in v0.29.0
func (r *ProblemMapperRegistry) Frozen() bool
Frozen reports whether the registry is frozen.
func (*ProblemMapperRegistry) Map ¶ added in v0.29.0
func (r *ProblemMapperRegistry) Map(err error) *Problem
Map converts an error into a Problem. It checks registered mappers in order; the first matching mapper wins. If no mapper matches, the fallback sanitizer produces a 500 problem.
If err is nil, Map returns nil. If err is already a *Problem, Map returns it as-is.
func (*ProblemMapperRegistry) Register ¶ added in v0.29.0
func (r *ProblemMapperRegistry) Register(matcher ProblemMatcher, mapper ProblemMapper) error
Register associates a mapper with a matcher. When Map encounters an error that matches the matcher, the mapper is invoked. Registration order matters: the first matching mapper wins.
Returns an error if matcher or mapper is nil.
func (*ProblemMapperRegistry) SetFallback ¶ added in v0.29.0
func (r *ProblemMapperRegistry) SetFallback(mapper ProblemMapper) error
SetFallback sets the fallback mapper invoked when no registered mapper matches. If nil is passed, the default sanitizer is used. Returns ErrProblemRegistryFrozen if the registry is frozen.
type ProblemMatcher ¶ added in v0.29.0
ProblemMatcher determines whether an error should be handled by a specific mapper. It typically uses errors.As to inspect the error chain. Returns true if the mapper should handle this error.
type ProblemViolation ¶ added in v0.29.0
type ProblemViolation struct {
// Field is the JSON/query/path/header field name that violated a
// constraint. Uses the wire name, not the Go struct field name.
Field string `json:"field"`
// Rule is the validation rule that was violated (e.g. "required",
// "min", "max_length").
Rule string `json:"rule"`
// Message is a human-readable description of the violation.
Message string `json:"message"`
}
ProblemViolation represents a single validation violation in a Problem response.
type RespData ¶ added in v0.10.4
type RespData struct {
Code int `json:"code"`
Status int `json:"status"`
Message string `json:"message"`
Type RespType `json:"type"`
JSON any `json:"description"`
PrintData *Receipt `json:"receipt"`
Attachment *FileResponse `json:"attachment"`
PreBuiltErrors *[]ErrorResponse `json:"-"` // when set, used instead of GetErrorsArray (e.g. for PublicDescription)
}
RespData holds all fields needed to construct an HTTP response.
type RespType ¶ added in v0.10.4
type RespType int
RespType identifies the kind of response payload to send.
type ResponseHandler ¶
type ResponseHandler interface {
OK(w webFramework.WebFramework, resp any)
OKWithReceipt(w webFramework.WebFramework, resp any, receipt *Receipt)
OKWithAttachment(w webFramework.WebFramework, file *FileResponse)
Error(w webFramework.WebFramework, err error)
}
ResponseHandler defines the interface for sending success and error HTTP responses.
type StatusAwareResponder ¶ added in v0.29.0
type StatusAwareResponder interface {
OKWithStatus(w webFramework.WebFramework, status int, resp any)
OKWithStatusAndHeaders(w webFramework.WebFramework, status int, headers map[string]string, resp any)
}
StatusAwareResponder is an optional interface that responders can implement to support configurable success statuses and response headers. WebHanlder implements this interface. Custom ResponseHandler implementations are not required to implement it; callers that need status-aware responses should type-assert to this interface.
type WebHanlder ¶ added in v0.15.0
WebHanlder holds description lookup maps for building API error responses.
func (WebHanlder) Error ¶ added in v0.15.0
func (m WebHanlder) Error(w webFramework.WebFramework, err error)
Error handles an error by logging it and sending an appropriate error response to the client.
func (WebHanlder) GetErrorsArray ¶ added in v0.15.0
func (m WebHanlder) GetErrorsArray(message string, data any) []ErrorResponse
GetErrorsArray builds a slice of ErrorResponse from a message and data using the handler's error description map.
func (WebHanlder) OK ¶ added in v0.15.0
func (m WebHanlder) OK(w webFramework.WebFramework, resp any)
OK sends a successful JSON response with HTTP 200 and the given data.
func (WebHanlder) OKWithAttachment ¶ added in v0.15.0
func (m WebHanlder) OKWithAttachment(w webFramework.WebFramework, attachment *FileResponse)
OKWithAttachment sends a successful file-attachment response with HTTP 200.
func (WebHanlder) OKWithReceipt ¶ added in v0.15.0
func (m WebHanlder) OKWithReceipt(w webFramework.WebFramework, resp any, receipt *Receipt)
OKWithReceipt sends a successful JSON response with an optional printable receipt.
func (WebHanlder) OKWithStatus ¶ added in v0.29.0
func (m WebHanlder) OKWithStatus(w webFramework.WebFramework, status int, resp any)
OKWithStatus sends a successful JSON response with the given HTTP status and data. The status must be a valid 2xx code. For 204 and 205, the response body is suppressed (no JSON is written). This is an additive, opt-in method; the default OK continues to use 200.
func (WebHanlder) OKWithStatusAndHeaders ¶ added in v0.29.0
func (m WebHanlder) OKWithStatusAndHeaders(w webFramework.WebFramework, status int, headers map[string]string, resp any)
OKWithStatusAndHeaders sends a successful JSON response with the given HTTP status, static response headers, and data. Headers are applied before the body is written. For 204 and 205, the body is suppressed but headers are still applied.
func (WebHanlder) Respond ¶ added in v0.15.0
func (m WebHanlder) Respond(code, status int, message string, data any, abort bool, w webFramework.WebFramework)
Respond sends a JSON response with the given code, status, message, and data, optionally aborting the request chain.
func (WebHanlder) RespondWithAttachment ¶ added in v0.15.0
func (m WebHanlder) RespondWithAttachment(code, status int, message string, file *FileResponse, abort bool, w webFramework.WebFramework)
RespondWithAttachment sends a file-attachment response with the given code, status, and message.
func (WebHanlder) RespondWithReceipt ¶ added in v0.15.0
func (m WebHanlder) RespondWithReceipt(code, status int, message string, data any, printData *Receipt, abort bool, w webFramework.WebFramework)
RespondWithReceipt sends a JSON response with an optional printable receipt and abort control.
type WsRemoteResponse ¶
type WsRemoteResponse struct {
Status int `json:"status"`
Description string `json:"description"`
Result any `json:"result,omitempty"`
ErrorData []ErrorResponse `json:"errors,omitempty"`
}
WsRemoteResponse represents the standard structure of a remote API response.
func (WsRemoteResponse) ToErrorState ¶ added in v0.1.7
func (e WsRemoteResponse) ToErrorState() ErrorState
ToErrorState converts a WsRemoteResponse into an ErrorState for error chaining.
type WsResponse ¶
type WsResponse struct {
Status int `json:"status"`
Description string `json:"description"`
Result any `json:"result,omitempty"`
ErrorData any `json:"errors,omitempty"`
PrintReceipt *Receipt `json:"printReceipt,omitempty"`
}
WsResponse represents the HTTP response sent to the client.
func (WsResponse) LogValue ¶ added in v0.22.5
func (r WsResponse) LogValue() slog.Value
LogValue returns a structured slog.Value for logging the WsResponse, redacting error details on failure.