extra loggng and error wraps (#2155)

## Description

Adds info logging on all throttling responses,
and some extra error handling in container
resolvers.

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

- [x]  No 

## Type of change

- [x] 🧹 Tech Debt/Cleanup

## Test Plan

- [x] 💪 Manual
This commit is contained in:
Keepers 2023-01-18 09:43:19 -07:00 committed by GitHub
parent dc17c68074
commit e3b6d035fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 22 deletions

View File

@ -26,15 +26,13 @@ func (cfc *contactFolderCache) populateContactRoot(
) error { ) error {
f, err := cfc.getter.GetContainerByID(ctx, cfc.userID, directoryID) f, err := cfc.getter.GetContainerByID(ctx, cfc.userID, directoryID)
if err != nil { if err != nil {
return errors.Wrapf( return support.ConnectorStackErrorTraceWrap(err, "fetching root folder")
err,
"fetching root contact folder: "+support.ConnectorStackErrorTrace(err))
} }
temp := graph.NewCacheFolder(f, path.Builder{}.Append(baseContainerPath...)) temp := graph.NewCacheFolder(f, path.Builder{}.Append(baseContainerPath...))
if err := cfc.addFolder(temp); err != nil { if err := cfc.addFolder(temp); err != nil {
return errors.Wrap(err, "adding cache root") return errors.Wrap(err, "adding resolver dir")
} }
return nil return nil
@ -50,16 +48,16 @@ func (cfc *contactFolderCache) Populate(
baseContainerPather ...string, baseContainerPather ...string,
) error { ) error {
if err := cfc.init(ctx, baseID, baseContainerPather); err != nil { if err := cfc.init(ctx, baseID, baseContainerPather); err != nil {
return err return errors.Wrap(err, "initializing")
} }
err := cfc.enumer.EnumerateContainers(ctx, cfc.userID, baseID, cfc.addFolder) err := cfc.enumer.EnumerateContainers(ctx, cfc.userID, baseID, cfc.addFolder)
if err != nil { if err != nil {
return err return errors.Wrap(err, "enumerating containers")
} }
if err := cfc.populatePaths(ctx); err != nil { if err := cfc.populatePaths(ctx); err != nil {
return errors.Wrap(err, "contacts resolver") return errors.Wrap(err, "populating paths")
} }
return nil return nil

View File

@ -31,7 +31,7 @@ func (ecc *eventCalendarCache) Populate(
err := ecc.enumer.EnumerateContainers(ctx, ecc.userID, "", ecc.addFolder) err := ecc.enumer.EnumerateContainers(ctx, ecc.userID, "", ecc.addFolder)
if err != nil { if err != nil {
return err return errors.Wrap(err, "enumerating containers")
} }
return nil return nil
@ -41,20 +41,20 @@ func (ecc *eventCalendarCache) Populate(
// @returns error iff the required values are not accessible. // @returns error iff the required values are not accessible.
func (ecc *eventCalendarCache) AddToCache(ctx context.Context, f graph.Container) error { func (ecc *eventCalendarCache) AddToCache(ctx context.Context, f graph.Container) error {
if err := checkIDAndName(f); err != nil { if err := checkIDAndName(f); err != nil {
return errors.Wrap(err, "adding cache folder") return errors.Wrap(err, "validating container")
} }
temp := graph.NewCacheFolder(f, path.Builder{}.Append(*f.GetDisplayName())) temp := graph.NewCacheFolder(f, path.Builder{}.Append(*f.GetDisplayName()))
if err := ecc.addFolder(temp); err != nil { if err := ecc.addFolder(temp); err != nil {
return errors.Wrap(err, "adding cache folder") return errors.Wrap(err, "adding container")
} }
// Populate the path for this entry so calls to PathInCache succeed no matter // Populate the path for this entry so calls to PathInCache succeed no matter
// when they're made. // when they're made.
_, err := ecc.IDToPath(ctx, *f.GetId()) _, err := ecc.IDToPath(ctx, *f.GetId())
if err != nil { if err != nil {
return errors.Wrap(err, "adding cache entry") return errors.Wrap(err, "setting path to container id")
} }
return nil return nil

View File

@ -35,7 +35,7 @@ func (mc *mailFolderCache) populateMailRoot(
f, err := mc.getter.GetContainerByID(ctx, mc.userID, fldr) f, err := mc.getter.GetContainerByID(ctx, mc.userID, fldr)
if err != nil { if err != nil {
return errors.Wrap(err, "fetching root folder"+support.ConnectorStackErrorTrace(err)) return support.ConnectorStackErrorTraceWrap(err, "fetching root folder")
} }
if fldr == DefaultMailFolder { if fldr == DefaultMailFolder {
@ -44,7 +44,7 @@ func (mc *mailFolderCache) populateMailRoot(
temp := graph.NewCacheFolder(f, path.Builder{}.Append(directory)) temp := graph.NewCacheFolder(f, path.Builder{}.Append(directory))
if err := mc.addFolder(temp); err != nil { if err := mc.addFolder(temp); err != nil {
return errors.Wrap(err, "initializing mail resolver") return errors.Wrap(err, "adding resolver dir")
} }
} }
@ -62,16 +62,16 @@ func (mc *mailFolderCache) Populate(
baseContainerPath ...string, baseContainerPath ...string,
) error { ) error {
if err := mc.init(ctx); err != nil { if err := mc.init(ctx); err != nil {
return err return errors.Wrap(err, "initializing")
} }
err := mc.enumer.EnumerateContainers(ctx, mc.userID, "", mc.addFolder) err := mc.enumer.EnumerateContainers(ctx, mc.userID, "", mc.addFolder)
if err != nil { if err != nil {
return err return errors.Wrap(err, "enumerating containers")
} }
if err := mc.populatePaths(ctx); err != nil { if err := mc.populatePaths(ctx); err != nil {
return errors.Wrap(err, "mail resolver") return errors.Wrap(err, "populating paths")
} }
return nil return nil

View File

@ -1,7 +1,7 @@
package graph package graph
import ( import (
nethttp "net/http" "net/http"
"net/http/httputil" "net/http/httputil"
"os" "os"
"strings" "strings"
@ -47,7 +47,7 @@ func CreateAdapter(tenant, client, secret string) (*msgraphsdk.GraphRequestAdapt
} }
// CreateHTTPClient creates the httpClient with middlewares and timeout configured // CreateHTTPClient creates the httpClient with middlewares and timeout configured
func CreateHTTPClient() *nethttp.Client { func CreateHTTPClient() *http.Client {
clientOptions := msgraphsdk.GetDefaultClientOptions() clientOptions := msgraphsdk.GetDefaultClientOptions()
middlewares := msgraphgocore.GetDefaultMiddlewaresWithOptions(&clientOptions) middlewares := msgraphgocore.GetDefaultMiddlewaresWithOptions(&clientOptions)
middlewares = append(middlewares, &LoggingMiddleware{}) middlewares = append(middlewares, &LoggingMiddleware{})
@ -67,8 +67,8 @@ type LoggingMiddleware struct{}
func (handler *LoggingMiddleware) Intercept( func (handler *LoggingMiddleware) Intercept(
pipeline khttp.Pipeline, pipeline khttp.Pipeline,
middlewareIndex int, middlewareIndex int,
req *nethttp.Request, req *http.Request,
) (*nethttp.Response, error) { ) (*http.Response, error) {
var ( var (
ctx = req.Context() ctx = req.Context()
resp, err = pipeline.Next(req, middlewareIndex) resp, err = pipeline.Next(req, middlewareIndex)
@ -82,6 +82,11 @@ func (handler *LoggingMiddleware) Intercept(
return resp, err return resp, err
} }
// special case for supportability: log all throttling cases.
if resp.StatusCode == http.StatusTooManyRequests {
logger.Ctx(ctx).Infow("graph api throttling", "method", req.Method, "url", req.URL)
}
if logger.DebugAPI || os.Getenv(logGraphRequestsEnvKey) != "" { if logger.DebugAPI || os.Getenv(logGraphRequestsEnvKey) != "" {
respDump, _ := httputil.DumpResponse(resp, true) respDump, _ := httputil.DumpResponse(resp, true)

View File

@ -89,8 +89,20 @@ func concatenateStringFromPointers(orig string, pointers []*string) string {
return orig return orig
} }
// ConnectorStackErrorTrace is a helper function that wraps the // ConnectorStackErrorTraceWrap is a helper function that wraps the
// stack trace for oDataError types from querying the M365 back store. // stack trace for oDataErrors (if the error has one) onto the prefix.
// If no stack trace is found, wraps the error with only the prefix.
func ConnectorStackErrorTraceWrap(e error, prefix string) error {
cset := ConnectorStackErrorTrace(e)
if len(cset) > 0 {
return errors.Wrap(e, prefix+": "+cset)
}
return errors.Wrap(e, prefix)
}
// ConnectorStackErrorTracew is a helper function that extracts
// the stack trace for oDataErrors, if the error has one.
func ConnectorStackErrorTrace(e error) string { func ConnectorStackErrorTrace(e error) string {
eMessage := "" eMessage := ""