centralized sdk err is checker (#3066)

Adds a package pkg/err which houses all internal-
to-external error mappings.  This helps centralize
error.Is checks for sdk consumers, without corso
distributing checkable error wrappers across
multiple pkg/** locations.

---

#### Does this PR need a docs update or release note?

- [x]  No

#### Type of change

- [x] 🤖 Supportability/Tests

#### Test Plan

- [x]  Unit test
This commit is contained in:
Keepers 2023-04-07 15:20:59 -06:00 committed by GitHub
parent f38f323726
commit 47cf403cca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 82 additions and 0 deletions

45
src/pkg/err/err.go Normal file
View File

@ -0,0 +1,45 @@
package err
import (
"errors"
"github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/pkg/repository"
)
// expose enums, rather than errors, for Is checks. The enum should
// map to a specific internal error that can be used for the actual
// errors.Is comparison.
type errEnum string
const (
RepoAlreadyExists errEnum = "repository-already-exists"
BackupNotFound errEnum = "backup-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},
BackupNotFound: {repository.ErrorBackupNotFound},
ServiceNotEnabled: {graph.ErrServiceNotEnabled},
}
// Is checks if the provided error contains an internal error that matches
// the public error category.
func Is(err error, enum errEnum) bool {
esl, ok := internalToExternal[enum]
if !ok {
return false
}
for _, e := range esl {
if errors.Is(err, e) {
return true
}
}
return false
}

37
src/pkg/err/err_test.go Normal file
View File

@ -0,0 +1,37 @@
package err
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/repository"
)
type ErrUnitSuite struct {
tester.Suite
}
func TestErrUnitSuite(t *testing.T) {
suite.Run(t, &ErrUnitSuite{Suite: tester.NewUnitSuite(t)})
}
func (suite *ErrUnitSuite) TestIs() {
table := []struct {
is errEnum
input error
}{
{RepoAlreadyExists, repository.ErrorRepoAlreadyExists},
{BackupNotFound, repository.ErrorBackupNotFound},
{ServiceNotEnabled, graph.ErrServiceNotEnabled},
}
for _, test := range table {
suite.Run(string(test.is), func() {
assert.True(suite.T(), Is(test.input, test.is))
assert.False(suite.T(), Is(assert.AnError, test.is))
})
}
}