{"record":{"id":"8a061958e22e5e73","repo":"kataras/iris","slug":"at-least-one-context-response-handler-function-is","errorCode":null,"errorMessage":"at least one context response handler function is required","messagePattern":"at least one context response handler function is required","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"x/errors/handlers.go","lineNumber":335,"sourceCode":"// Example Code:\n//\n//\tapp.Post(\"/\", errors.Intercept(func(ctx iris.Context, req *CreateRequest, resp *CreateResponse) error{ ... }), errors.CreateHandler(service.Create))\nfunc Intercept[T, R any](responseHandlers ...ContextResponseFunc[T, R]) context.Handler {\n\tif len(responseHandlers) == 0 {\n\t\treturn nil\n\t}\n\n\tresponseHandler := joinContextResponseFuncs(responseHandlers)\n\n\treturn func(ctx *context.Context) {\n\t\tctx.Values().Set(contextResponseHandlerFuncKey, responseHandler)\n\t\tctx.Next()\n\t}\n}\n\nfunc joinContextResponseFuncs[T, R any](responseHandlerFuncs []ContextResponseFunc[T, R]) ContextResponseFunc[T, R] {\n\tif len(responseHandlerFuncs) == 0 || responseHandlerFuncs[0] == nil {\n\t\tpanic(\"at least one context response handler function is required\")\n\t}\n\n\tif len(responseHandlerFuncs) == 1 {\n\t\treturn responseHandlerFuncs[0]\n\t}\n\n\treturn func(ctx *context.Context, req T, resp *R) error {\n\t\tfor _, handler := range responseHandlerFuncs {\n\t\t\tif handler == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif err := handler(ctx, req, resp); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\treturn nil","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/x/errors/handlers.go#L317-L353","documentation":"joinContextResponseFuncs composes a list of ContextResponseFunc handlers and panics when the list is empty or the first handler is nil, since composing zero response handlers is meaningless.","triggerScenarios":"Calling x/errors Intercept(...) (which calls joinContextResponseFuncs) with no response handlers or with a nil first element.","commonSituations":"Same as the request-side twin: dynamically built handler slices left empty, or nil entries from map lookups.","solutions":["Provide at least one non-nil ContextResponseFunc to Intercept","Sanitize the slice (drop nils) before calling Intercept","Return a default/no-op handler when the list would be empty"],"exampleFix":"// before\nresp := xerrors.Intercept(nilHandlers...)\n// after\nif len(handlers) > 0 && handlers[0] != nil {\n    resp = xerrors.Intercept(handlers...)\n}","handlingStrategy":"validation","validationCode":"func canJoinResponseFuncs[T, R any](fs []ContextResponseFunc[T, R]) bool {\n    return len(fs) > 0 && fs[0] != nil\n}","typeGuard":null,"tryCatchPattern":"defer func() { if r := recover(); r != nil { log.Printf(\"response chain panic: %v\", r) } }()\nh := joinContextResponseFuncs(handlers)","preventionTips":["Filter nils from dynamically built response handler lists","Assert non-empty chains in tests","Provide a default no-op response handler for empty cases"],"tags":["go","panic","intercept","handlers"],"backgroundTag":"empty-handler-chain","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}