Issue #144 Commit adds ability to add message id to errors (#151)

* Issue #144 Commit adds ability to add message id to errors
Commit related to Issue #140 to find cascading errors associated with
the failures GraphConnector queries.

* Issue 144: Update to go libraries to import multierror

* Reduced error package to include certain multierror interface.

* Issue #144: Added format interface for append. Added additional testing for multiple wrapping of error.
This commit is contained in:
Danny 2022-06-08 08:59:59 -04:00 committed by GitHub
parent ebae1ed037
commit ddc9cd2c25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 159 additions and 0 deletions

View File

@ -41,6 +41,8 @@ require (
github.com/dustin/go-humanize v1.0.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect
github.com/golang-jwt/jwt v3.2.1+incompatible // indirect github.com/golang-jwt/jwt v3.2.1+incompatible // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect

View File

@ -177,6 +177,10 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=

View File

@ -0,0 +1,93 @@
package connector
import (
"fmt"
"strings"
"github.com/pkg/errors"
multierror "github.com/hashicorp/go-multierror"
msgraph_errors "github.com/microsoftgraph/msgraph-sdk-go/models/odataerrors"
)
// WrapErrorAndAppend helper function used to attach identifying information to an error
// and return it as a mulitierror
func WrapAndAppend(identifier string, e error, previous error) error {
return multierror.Append(previous, errors.Wrap(e, identifier))
}
// WrapErrorAndAppendf format version of WrapErrorAndAppend
func WrapAndAppendf(identifier interface{}, e error, previous error) error {
return multierror.Append(previous, errors.Wrapf(e, "%v", identifier))
}
// ListErrors is a helper method used to return the string of errors when
// the multiError library is used.
// depends on ConnectorStackErrorTrace
func ListErrors(multi multierror.Error) string {
aString := ""
for idx, err := range multi.Errors {
detail := ConnectorStackErrorTrace(err)
if detail == "" {
detail = fmt.Sprintf("%v", err)
}
aString = aString + fmt.Sprintf("\n\tErr: %d %v", idx+1, detail)
}
return aString
}
// concatenateStringFromPointers is a helper funtion that adds
// strings to the originalMessage iff the pointer is not nil
func concatenateStringFromPointers(orig string, pointers []*string) string {
for _, pointer := range pointers {
if pointer != nil {
orig = strings.Join([]string{orig, *pointer}, " ")
}
}
return orig
}
// ConnectorStackErrorTrace is a helper function that wraps the
// stack trace for oDataError types from querying the M365 back store.
func ConnectorStackErrorTrace(e error) string {
eMessage := ""
if oDataError, ok := e.(msgraph_errors.ODataErrorable); ok {
// Get MainError
mainErr := oDataError.GetError()
// message *string
// target *string
// code *string
// details ErrorDetailsable
// Ignoring Additonal Detail
code := mainErr.GetCode()
subject := mainErr.GetMessage()
target := mainErr.GetTarget()
details := mainErr.GetDetails()
inners := mainErr.GetInnererror()
eMessage = concatenateStringFromPointers(eMessage,
[]*string{code, subject, target})
// Get Error Details
// code, message, target
if details != nil {
eMessage = eMessage + "\nDetails Section:"
for idx, detail := range details {
dMessage := fmt.Sprintf("Detail %d:", idx)
c := detail.GetCode()
m := detail.GetMessage()
t := detail.GetTarget()
dMessage = concatenateStringFromPointers(dMessage,
[]*string{c, m, t})
eMessage = eMessage + dMessage
}
}
if inners != nil {
fmt.Println("Inners not nil")
eMessage = eMessage + "\nConnector Section:"
client := inners.GetClientRequestId()
rId := inners.GetRequestId()
eMessage = concatenateStringFromPointers(eMessage,
[]*string{client, rId})
}
}
return eMessage
}

View File

@ -0,0 +1,60 @@
package connector
import (
"errors"
"fmt"
"strings"
"testing"
multierror "github.com/hashicorp/go-multierror"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
type GraphConnectorErrorSuite struct {
suite.Suite
}
func TestGraphConnectorErrorSuite(t *testing.T) {
suite.Run(t, new(GraphConnectorErrorSuite))
}
func (suite *GraphConnectorErrorSuite) TestWrapAndAppend() {
err1 := fmt.Errorf("New Error")
err2 := errors.New("I have two")
returnErr := WrapAndAppend("arc376", err2, err1)
suite.True(strings.Contains(returnErr.Error(), "arc376"))
suite.Error(returnErr)
multi := &multierror.Error{Errors: []error{err1, err2}}
suite.True(strings.Contains(ListErrors(*multi), "two")) // Does not contain the wrapped information
suite.T().Log(ListErrors(*multi))
}
func (suite *GraphConnectorErrorSuite) TestWrapAndAppend_Add3() {
errOneTwo := WrapAndAppend("user1", assert.AnError, assert.AnError)
combined := WrapAndAppend("unix36", assert.AnError, errOneTwo)
allErrors := WrapAndAppend("fxi92874", assert.AnError, combined)
suite.True(strings.Contains(combined.Error(), "unix36"))
suite.True(strings.Contains(combined.Error(), "user1"))
suite.True(strings.Contains(allErrors.Error(), "fxi92874"))
}
func (suite *GraphConnectorErrorSuite) TestWrapAndAppendf() {
err1 := assert.AnError
err2 := assert.AnError
combined := WrapAndAppendf(134323, err2, err1)
suite.True(strings.Contains(combined.Error(), "134323"))
}
func (suite *GraphConnectorErrorSuite) TestConcatenateStringFromPointers() {
var s1, s2, s3 *string
var outString string
v1 := "Corso"
v3 := "remains"
s1 = &v1
s3 = &v3
outString = concatenateStringFromPointers(outString, []*string{s1, s2, s3})
suite.True(strings.Contains(outString, v1))
suite.True(strings.Contains(outString, v3))
}