fix(detector/github): Github dependency graph API request will be retried on error (#1650)
* fix: Github dependency graph API request will be retried on error * fix: github dependency graph: error handling * github dependency graph: fix retry max
This commit is contained in:
		@@ -12,7 +12,9 @@ import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/cenkalti/backoff"
 | 
			
		||||
	"github.com/future-architect/vuls/errof"
 | 
			
		||||
	"github.com/future-architect/vuls/logging"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"golang.org/x/oauth2"
 | 
			
		||||
)
 | 
			
		||||
@@ -240,25 +242,44 @@ func fetchDependencyGraph(r *models.ScanResult, httpClient *http.Client, owner,
 | 
			
		||||
	req.Header.Set("Accept", "application/vnd.github.hawkgirl-preview+json")
 | 
			
		||||
	req.Header.Set("Content-Type", "application/json")
 | 
			
		||||
 | 
			
		||||
	resp, err := httpClient.Do(req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer resp.Body.Close()
 | 
			
		||||
 | 
			
		||||
	body, err := io.ReadAll(resp.Body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	graph := DependencyGraph{}
 | 
			
		||||
	if err := json.Unmarshal(body, &graph); err != nil {
 | 
			
		||||
	count, retryMax := 0, 10
 | 
			
		||||
	countCheck := func(err error) error {
 | 
			
		||||
		if count == retryMax {
 | 
			
		||||
			return backoff.Permanent(err)
 | 
			
		||||
		}
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	operation := func() error {
 | 
			
		||||
		count++
 | 
			
		||||
		resp, err := httpClient.Do(req)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return countCheck(err)
 | 
			
		||||
		}
 | 
			
		||||
		defer resp.Body.Close()
 | 
			
		||||
 | 
			
		||||
	if graph.Data.Repository.URL == "" {
 | 
			
		||||
		return errof.New(errof.ErrFailedToAccessGithubAPI,
 | 
			
		||||
			fmt.Sprintf("Failed to access to GitHub API. Response: %s", string(body)))
 | 
			
		||||
		body, err := io.ReadAll(resp.Body)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return countCheck(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err := json.Unmarshal(body, &graph); err != nil {
 | 
			
		||||
			return countCheck(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(graph.Errors) > 0 || graph.Data.Repository.URL == "" {
 | 
			
		||||
			return countCheck(errof.New(errof.ErrFailedToAccessGithubAPI,
 | 
			
		||||
				fmt.Sprintf("Failed to access to GitHub API. Response: %s", string(body))))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	notify := func(err error, t time.Duration) {
 | 
			
		||||
		logging.Log.Warnf("Failed trial (count: %d). retrying in %s. err: %+v", count, t, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = backoff.RetryNotify(operation, backoff.NewExponentialBackOff(), notify); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dependenciesAfter = ""
 | 
			
		||||
@@ -340,4 +361,13 @@ type DependencyGraph struct {
 | 
			
		||||
			} `json:"dependencyGraphManifests"`
 | 
			
		||||
		} `json:"repository"`
 | 
			
		||||
	} `json:"data"`
 | 
			
		||||
	Errors []struct {
 | 
			
		||||
		Type      string        `json:"type,omitempty"`
 | 
			
		||||
		Path      []interface{} `json:"path,omitempty"`
 | 
			
		||||
		Locations []struct {
 | 
			
		||||
			Line   int `json:"line"`
 | 
			
		||||
			Column int `json:"column"`
 | 
			
		||||
		} `json:"locations,omitempty"`
 | 
			
		||||
		Message string `json:"message"`
 | 
			
		||||
	} `json:"errors,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user