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
- func DefaultErrorHandler() gin.HandlerFunc
- func NewHandler[Req any, Resp any](method func(ctx context.Context, req *Req) (*Resp, error), ...) gin.HandlerFunc
- func NewHandlerWithOptions[Req any, Resp any](method func(ctx context.Context, req *Req) (*Resp, error), ...) gin.HandlerFunc
- type BizCode
- type CodedError
- type Error
- type HandlerOption
- type PreValidateHook
- type Response
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.
Note: on bind/validate failure the handler calls c.Error and returns without calling c.Abort(). Downstream middleware in the same handler chain will still execute. Register DefaultErrorHandler (or an equivalent error-writing middleware) after this handler to write the error response and abort the chain.
func NewHandlerWithOptions ¶ added in v0.6.0
func NewHandlerWithOptions[Req any, Resp any]( method func(ctx context.Context, req *Req) (*Resp, error), opts ...HandlerOption[Req, Resp], ) gin.HandlerFunc
NewHandlerWithOptions creates a gin.HandlerFunc that binds JSON, runs pre-validation hooks, validates, and calls the service method through a handlerx interceptor chain.
Pre-validation hooks run after JSON binding and before Validate(), in the order they are registered. Hook errors are recorded with c.Error and stop the request before validation or service execution. Hook panics are recovered and converted to panicx.ErrPanic-compatible errors.
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 HandlerOption ¶ added in v0.6.0
HandlerOption configures a handler built by NewHandlerWithOptions.
func WithInterceptors ¶ added in v0.6.0
func WithInterceptors[Req any, Resp any]( xs ...handlerx.Interceptor[*Req, *Resp], ) HandlerOption[Req, Resp]
WithInterceptors registers handlerx interceptors for the service method. Interceptors run inside the runtime recovery interceptor, preserving the behavior of NewHandler.
func WithPreValidateHook ¶ added in v0.6.0
func WithPreValidateHook[Req any, Resp any](hook PreValidateHook[Req]) HandlerOption[Req, Resp]
WithPreValidateHook registers hook to run after JSON binding and before request validation. Hooks run in registration order.
type PreValidateHook ¶ added in v0.6.0
PreValidateHook runs after JSON binding and before request validation. Hooks may mutate req; later hooks, Validate, and the service method observe those changes.
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.