Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve error handling when TTL is invalid #106

Merged
merged 3 commits into from
Feb 21, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Allow ambiguous TTL error
punmechanic committed Feb 21, 2024
commit b8ce18876b7fee770315fed28de7fdd10f128e50
14 changes: 11 additions & 3 deletions cli/error.go
Original file line number Diff line number Diff line change
@@ -137,6 +137,11 @@ func (o TimeToLiveError) Code() int {
}

func (o TimeToLiveError) Error() string {
if o.MaxDuration == 0 && o.RequestedDuration == 0 {
// Duration is ambiguous/was not specified by AWS, so we return a generic message instead.
return "the TTL you requested exceeds the maximum TTL for this configuration"
}

// We cast to int to discard decimal places
return fmt.Sprintf("you requested a TTL of %d hours, but the maximum for this configuration is %d hours", int(o.RequestedDuration.Hours()), int(o.MaxDuration.Hours()))
}
@@ -151,11 +156,14 @@ func tryParseTimeToLiveError(err error) (error, bool) {
var providedValue, maxValue time.Duration
// This is no more specific type than this, and yes, unfortunately the error message includes the count.
formatOne := "1 validation error detected: Value '%d' at 'durationSeconds' failed to satisfy constraint: Member must have value less than or equal to %d"
if n, parseErr := fmt.Sscanf(awsErr.Message(), formatOne, &providedValue, &maxValue); parseErr != nil || n != 2 {
return nil, false
if n, parseErr := fmt.Sscanf(awsErr.Message(), formatOne, &providedValue, &maxValue); parseErr == nil && n == 2 {
return TimeToLiveError{MaxDuration: maxValue * time.Second, RequestedDuration: providedValue * time.Second}, true
}

return TimeToLiveError{MaxDuration: maxValue * time.Second, RequestedDuration: providedValue * time.Second}, true
formatAmbiguousMaximum := "The requested DurationSeconds exceeds the MaxSessionDuration set for this role."
if strings.Compare(awsErr.Message(), formatAmbiguousMaximum) == 0 {
return TimeToLiveError{MaxDuration: 0, RequestedDuration: 0}, true
}
}

return nil, false
36 changes: 26 additions & 10 deletions cli/error_test.go
Original file line number Diff line number Diff line change
@@ -9,15 +9,31 @@ import (
)

func Test_tryParseTimeToLiveError(t *testing.T) {
validationError := awserr.New("ValidationError", "Value '86400' at 'durationSeconds' failed to satisfy constraint: Member must have value less than or equal to 43200", nil)
err, ok := tryParseTimeToLiveError(validationError)
t.Run("UnambiguousAmount", func(t *testing.T) {
validationError := awserr.New("ValidationError", "1 validation error detected: Value '86400' at 'durationSeconds' failed to satisfy constraint: Member must have value less than or equal to 43200", nil)
err, ok := tryParseTimeToLiveError(validationError)

require.True(t, ok)
require.NotNil(t, err)
require.Equal(t, err.Error(), "you requested a TTL of 24 hours, but the maximum for this configuration is 12 hours")
var ttlError TimeToLiveError
require.ErrorAs(t, err, &ttlError)
require.Equal(t, ttlError.MaxDuration, 43200*time.Second)
require.Equal(t, ttlError.RequestedDuration, 86400*time.Second)
require.Equal(t, ttlError.Code(), ExitCodeValueError)
require.True(t, ok)
require.NotNil(t, err)
require.Equal(t, err.Error(), "you requested a TTL of 24 hours, but the maximum for this configuration is 12 hours")
var ttlError TimeToLiveError
require.ErrorAs(t, err, &ttlError)
require.Equal(t, ttlError.MaxDuration, 43200*time.Second)
require.Equal(t, ttlError.RequestedDuration, 86400*time.Second)
require.Equal(t, ttlError.Code(), ExitCodeValueError)
})

t.Run("AmbiguousAmount", func(t *testing.T) {
validationError := awserr.New("ValidationError", "The requested DurationSeconds exceeds the MaxSessionDuration set for this role.", nil)
err, ok := tryParseTimeToLiveError(validationError)

require.True(t, ok)
require.NotNil(t, err)
require.Equal(t, err.Error(), "the TTL you requested exceeds the maximum TTL for this configuration")
var ttlError TimeToLiveError
require.ErrorAs(t, err, &ttlError)
require.Equal(t, ttlError.MaxDuration, time.Duration(0))
require.Equal(t, ttlError.RequestedDuration, time.Duration(0))
require.Equal(t, ttlError.Code(), ExitCodeValueError)
})
}