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:
parent
f38f323726
commit
47cf403cca
45
src/pkg/err/err.go
Normal file
45
src/pkg/err/err.go
Normal 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
37
src/pkg/err/err_test.go
Normal 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))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user