formalizes ErrApplicationThrottled (#4317)
adds graph error identification for application throttled and adds an ApplicationThrottled sentinel to pkg/errs for sdk consumer identification. --- #### Does this PR need a docs update or release note? - [x] ⛔ No #### Type of change - [x] 🌻 Feature #### Test Plan - [x] ⚡ Unit test - [x] 💚 E2E
This commit is contained in:
parent
b212c37fd3
commit
c1ec3c6648
@ -26,6 +26,7 @@ import (
|
||||
type errorCode string
|
||||
|
||||
const (
|
||||
applicationThrottled errorCode = "ApplicationThrottled"
|
||||
// this auth error is a catch-all used by graph in a variety of cases:
|
||||
// users without licenses, bad jwts, missing account permissions, etc.
|
||||
AuthenticationError errorCode = "AuthenticationError"
|
||||
@ -81,6 +82,10 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrApplicationThrottled occurs if throttling retries are exhausted and completely
|
||||
// fails out.
|
||||
ErrApplicationThrottled = clues.New("application throttled")
|
||||
|
||||
// The folder or item was deleted between the time we identified
|
||||
// it and when we tried to fetch data for it.
|
||||
ErrDeletedInFlight = clues.New("deleted in flight")
|
||||
@ -116,6 +121,11 @@ var (
|
||||
ErrResourceOwnerNotFound = clues.New("resource owner not found in tenant")
|
||||
)
|
||||
|
||||
func IsErrApplicationThrottled(err error) bool {
|
||||
return hasErrorCode(err, applicationThrottled) ||
|
||||
errors.Is(err, ErrApplicationThrottled)
|
||||
}
|
||||
|
||||
func IsErrAuthenticationError(err error) bool {
|
||||
return hasErrorCode(err, AuthenticationError)
|
||||
}
|
||||
|
||||
@ -94,6 +94,40 @@ func (suite *GraphErrorsUnitSuite) TestIsErrConnectionReset() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *GraphErrorsUnitSuite) TestIsErrApplicationThrottled() {
|
||||
table := []struct {
|
||||
name string
|
||||
err error
|
||||
expect assert.BoolAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "nil",
|
||||
err: nil,
|
||||
expect: assert.False,
|
||||
},
|
||||
{
|
||||
name: "non-matching",
|
||||
err: assert.AnError,
|
||||
expect: assert.False,
|
||||
},
|
||||
{
|
||||
name: "non-matching oDataErr",
|
||||
err: odErr("fnords"),
|
||||
expect: assert.False,
|
||||
},
|
||||
{
|
||||
name: "applicationThrottled oDataErr",
|
||||
err: odErr(string(applicationThrottled)),
|
||||
expect: assert.True,
|
||||
},
|
||||
}
|
||||
for _, test := range table {
|
||||
suite.Run(test.name, func() {
|
||||
test.expect(suite.T(), IsErrApplicationThrottled(test.err))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *GraphErrorsUnitSuite) TestIsErrAuthenticationError() {
|
||||
table := []struct {
|
||||
name string
|
||||
|
||||
@ -113,6 +113,10 @@ func (hw httpWrapper) Request(
|
||||
break
|
||||
}
|
||||
|
||||
if IsErrApplicationThrottled(err) {
|
||||
return nil, Stack(ictx, clues.Stack(ErrApplicationThrottled, err))
|
||||
}
|
||||
|
||||
var http2StreamErr http2.StreamError
|
||||
if !errors.As(err, &http2StreamErr) {
|
||||
return nil, Stack(ictx, err)
|
||||
|
||||
@ -360,6 +360,10 @@ func (aw *adapterWrap) Send(
|
||||
break
|
||||
}
|
||||
|
||||
if IsErrApplicationThrottled(err) {
|
||||
return nil, clues.Stack(ErrApplicationThrottled, err).WithTrace(1).WithClues(ictx)
|
||||
}
|
||||
|
||||
if !IsErrConnectionReset(err) && !connectionEnded.Compare(err.Error()) {
|
||||
return nil, clues.Stack(err).WithTrace(1).WithClues(ictx)
|
||||
}
|
||||
|
||||
@ -13,20 +13,22 @@ import (
|
||||
type errEnum string
|
||||
|
||||
const (
|
||||
RepoAlreadyExists errEnum = "repository-already-exists"
|
||||
ApplicationThrottled errEnum = "application-throttled"
|
||||
BackupNotFound errEnum = "backup-not-found"
|
||||
ServiceNotEnabled errEnum = "service-not-enabled"
|
||||
RepoAlreadyExists errEnum = "repository-already-exists"
|
||||
ResourceOwnerNotFound errEnum = "resource-owner-not-found"
|
||||
ServiceNotEnabled errEnum = "service-not-enabled"
|
||||
)
|
||||
|
||||
// map of enums to errors. We might want to re-use an enum for multiple
|
||||
// internal errors (ex: "ServiceNotEnabled" may exist in both graph and
|
||||
// non-graph producers).
|
||||
var internalToExternal = map[errEnum][]error{
|
||||
RepoAlreadyExists: {repository.ErrorRepoAlreadyExists},
|
||||
ApplicationThrottled: {graph.ErrApplicationThrottled},
|
||||
BackupNotFound: {repository.ErrorBackupNotFound},
|
||||
ServiceNotEnabled: {graph.ErrServiceNotEnabled},
|
||||
RepoAlreadyExists: {repository.ErrorRepoAlreadyExists},
|
||||
ResourceOwnerNotFound: {graph.ErrResourceOwnerNotFound},
|
||||
ServiceNotEnabled: {graph.ErrServiceNotEnabled},
|
||||
}
|
||||
|
||||
// Internal returns the internal errors which match to the public error category.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user