diff --git a/internal/wrappers/feature-flags-http.go b/internal/wrappers/feature-flags-http.go index 3f0c7731..e98b6029 100644 --- a/internal/wrappers/feature-flags-http.go +++ b/internal/wrappers/feature-flags-http.go @@ -4,8 +4,11 @@ import ( "encoding/json" "fmt" "net/http" + "strconv" "strings" + "time" + "github.com/checkmarx/ast-cli/internal/logger" "github.com/pkg/errors" "github.com/spf13/viper" @@ -87,6 +90,16 @@ func (f FeatureFlagsHTTPWrapper) GetSpecificFlag(flagName string) (*FeatureFlagR return &model, nil case http.StatusNotFound: return nil, errors.New("feature flags not found") + case http.StatusTooManyRequests: + waitSeconds := defaultRateLimitWaitSeconds + if retryAfter := resp.Header.Get("Retry-After"); retryAfter != "" { + if parsed, parseErr := strconv.Atoi(retryAfter); parseErr == nil && parsed > 0 { + waitSeconds = parsed + } + } + logger.PrintIfVerbose(fmt.Sprintf("Feature flags rate limited (429). Waiting %d seconds before retry.", waitSeconds)) + time.Sleep(time.Duration(waitSeconds) * time.Second) + return nil, errors.New("failed to load feature flags for tenant") default: return nil, errors.New("failed to load feature flags for tenant") } diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index a5718fbd..9b508d00 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -113,8 +113,10 @@ func GetSpecificFeatureFlag(featureFlagsWrapper FeatureFlagsWrapper, flagName st if len(featureFlags) == 0 || DefaultFFLoad { _ = HandleFeatureFlags(featureFlagsWrapper) } - // Take the value from FeatureFlags - return &FeatureFlagResponseModel{Name: flagName, Status: featureFlags[flagName]}, nil + defaultValue := featureFlags[flagName] + featureFlagsCache[flagName] = defaultValue // prevent re-fetch on next call + return &FeatureFlagResponseModel{Name: flagName, Status: defaultValue}, nil + } UpdateSpecificFeatureFlagMap(flagName, *specificFlag)