Documentation
¶
Overview ¶
Package httpruntime provides runtime helpers for generated HTTP handler functions. It defines the unified response envelope (Response), error types (Error, CodedError), and DefaultErrorHandler middleware for gin-based services.
Package httpruntime provides runtime helpers for generated HTTP handler functions. It defines the response envelope, error type, and CodedError interface used by generated .pb.http.go files.
Index ¶
Constants ¶
const ( // CodeOK is the response code for successful requests. CodeOK = 0 // CodeBadRequest is the response code for malformed request bodies (JSON parse errors). // The request body could not be decoded; the client should fix its serialization. CodeBadRequest = 1000 // CodeValidationErr is the response code for field-level constraint validation failures. // The request body was decoded successfully but one or more fields failed business rules. CodeValidationErr = 1001 // CodeDefaultErr is the response code used when no specific business code is available. // Message is always "internal error" — the original error is never exposed to the client. CodeDefaultErr = 5000 )
Variables ¶
This section is empty.
Functions ¶
func DefaultErrorHandler ¶
func DefaultErrorHandler() gin.HandlerFunc
DefaultErrorHandler returns a gin middleware that writes a JSON error response for any errors accumulated via c.Error() during handler execution. ValidationError maps to CodeValidationErr; all other errors use ErrResponse (see its doc for the business vs system error visibility contract). Only the last error (c.Errors.Last()) is used when multiple errors are present.
Logging contract: this middleware does NOT log errors. System errors (plain errors.New / fmt.Errorf) are hidden from the client response; to preserve the full error chain for debugging, log the error in the handler before calling c.Error(), or register a separate logging middleware that reads c.Errors:
// Option A: log in the handler
if err := svc.Create(req); err != nil {
logger.Error("create failed", "error", err)
_ = c.Error(err)
return
}
// Option B: separate logging middleware (registered before DefaultErrorHandler)
func LogErrors(logger *slog.Logger) gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
for _, e := range c.Errors {
logger.Error("request error", "error", e.Err)
}
}
}
Note: when the error is (or wraps) a *validateruntime.ValidationError, the response Msg is taken from the ValidationError itself, not from any outer wrapper.
WARNING: Generated handlers use c.Error(err)+return and do not write their own error responses. If this middleware is not registered, error paths will return HTTP 200 with an empty body. Always register DefaultErrorHandler (or a custom equivalent) on any router that serves generated handlers.
func NewHandler ¶ added in v0.3.0
func NewHandler[Req any, Resp any]( method func(ctx context.Context, req *Req) (*Resp, error), interceptors ...handlerx.Interceptor[*Req, *Resp], ) gin.HandlerFunc
NewHandler creates a gin.HandlerFunc that binds JSON, validates, and calls the service method through a handlerx interceptor chain. WithRecovery is always applied as the outermost interceptor. Additional interceptors are applied inside recovery, before the service method.
Types ¶
type BizCode ¶ added in v0.3.0
type BizCode int
BizCode is the business error code type for application-defined errors. Use errorx.Error[BizCode] to define typed business errors that integrate with ErrResponse without implementing CodedError manually:
var ErrUnprocessable = errorx.New(httpruntime.BizCode(1002), "invalid parameter combination")
BizCode values are application-defined 4-digit codes with no relation to HTTP status codes. The numeric value is carried as-is in the response Code field.
Reserved ranges:
0 success (CodeOK) 1000-1999 input errors — client data problems, message safe to expose 5000-5999 server errors — internal failures, message hidden from client
type CodedError ¶
CodedError may be implemented by application errors to supply a custom business error code (not an HTTP status code). If an error passed to ErrResponse implements this interface, its Code() value is used; otherwise the default code CodeDefaultErr applies.
type Error ¶
Error carries error details inside a Response. Fields is an optional map for structured error metadata (e.g. per-field validation failures).
type Response ¶
type Response struct {
Code int `json:"code"`
Data any `json:"data,omitempty"`
Error *Error `json:"error,omitempty"`
}
Response is the JSON envelope returned by all generated HTTP handlers. Code 0 indicates success; non-zero indicates an error.
func ErrResponse ¶
ErrResponse constructs an error Response from err. Code resolution order:
- If err (or any error in its chain) is *errorx.Error[BizCode], its Code field is used.
- If err implements CodedError, its Code() value is used.
- Otherwise the response code defaults to CodeDefaultErr and the message is "internal error" — the original error is NOT exposed to the client.
Error visibility contract:
- Business errors (BizCode / CodedError): message is safe to expose to clients. Wrap internal errors with a business error to control the client-visible message: errorx.Wrap(dbErr, BizCode(5001), "service unavailable")
- System errors (plain errors.New / fmt.Errorf): message is hidden from clients. Log the full error chain before or after calling ErrResponse to preserve internal context for debugging.
If err is nil, ErrResponse returns a generic CodeDefaultErr response.
func OKResponse ¶
OKResponse constructs a success Response with code CodeOK (0) and the given data.