Repository: datreeio/datree
Pull request #706 (2022-07-04 13:08:03)

fix: identify http request errors as network errors


Patch:
diff --git a/bl/validation/k8sValidator.go b/bl/validation/k8sValidator.go
index 09da469..19a2150 100644
--- a/bl/validation/k8sValidator.go
+++ b/bl/validation/k8sValidator.go
@@ -180,7 +180,7 @@ func (val *K8sValidator) validateResource(filepath string) (bool, []error, *vali
 			isValid = false
 			errString := res.Err.Error()
 
-			if utils.IsNetworkError(errString) {
+			if utils.IsNetworkError(res.Err) {
 				validationErrors = append(validationErrors, &InvalidK8sSchemaError{errString})
 			} else {
 				errorMessages := strings.Split(errString, "-")
diff --git a/pkg/cliClient/cliClient.go b/pkg/cliClient/cliClient.go
index f3f129b..0a70dba 100644
--- a/pkg/cliClient/cliClient.go
+++ b/pkg/cliClient/cliClient.go
@@ -8,7 +8,7 @@ type HTTPClient interface {
 	Request(method string, resourceURI string, body interface{}, headers map[string]string) (httpClient.Response, error)
 }
 type NetworkValidator interface {
-	IdentifyNetworkError(errStr string) error
+	IdentifyNetworkError(err error) error
 	IsLocalMode() bool
 }
 
diff --git a/pkg/cliClient/evaluation.go b/pkg/cliClient/evaluation.go
index acf8d81..98256d5 100644
--- a/pkg/cliClient/evaluation.go
+++ b/pkg/cliClient/evaluation.go
@@ -125,7 +125,7 @@ func (c *CliClient) RequestEvaluationPrerunData(tokenId string, isCi bool) (*Eva
 	res, err := c.httpClient.Request(http.MethodGet, "/cli/evaluation/tokens/"+tokenId+"/prerun?"+isCiQueryParam, nil, c.flagsHeaders)
 
 	if err != nil {
-		networkErr := c.networkValidator.IdentifyNetworkError(err.Error())
+		networkErr := c.networkValidator.IdentifyNetworkError(err)
 		if networkErr != nil {
 			return &EvaluationPrerunDataResponse{}, networkErr
 		}
@@ -211,7 +211,7 @@ func (c *CliClient) SendEvaluationResult(request *EvaluationResultRequest) (*Sen
 
 	httpRes, err := c.httpClient.Request(http.MethodPost, "/cli/evaluation/result", request, c.flagsHeaders)
 	if err != nil {
-		networkErr := c.networkValidator.IdentifyNetworkError(err.Error())
+		networkErr := c.networkValidator.IdentifyNetworkError(err)
 		if networkErr != nil {
 			return &SendEvaluationResultsResponse{}, networkErr
 		}
diff --git a/pkg/cliClient/tokens.go b/pkg/cliClient/tokens.go
index c40373b..15ee8f1 100644
--- a/pkg/cliClient/tokens.go
+++ b/pkg/cliClient/tokens.go
@@ -18,7 +18,7 @@ func (c *CliClient) CreateToken() (*CreateTokenResponse, error) {
 	res, err := c.httpClient.Request(http.MethodPost, "/cli/tokens/", nil, headers)
 
 	if err != nil {
-		networkErr := c.networkValidator.IdentifyNetworkError(err.Error())
+		networkErr := c.networkValidator.IdentifyNetworkError(err)
 		if networkErr != nil {
 			return nil, networkErr
 		}
diff --git a/pkg/networkValidator/networkValidator.go b/pkg/networkValidator/networkValidator.go
index b868edf..0b7c210 100644
--- a/pkg/networkValidator/networkValidator.go
+++ b/pkg/networkValidator/networkValidator.go
@@ -22,8 +22,8 @@ func (nv *NetworkValidator) SetOfflineMode(offlineMode string) {
 	nv.offlineMode = offlineMode
 }
 
-func (nv *NetworkValidator) IdentifyNetworkError(errStr string) error {
-	if utils.IsNetworkError(errStr) {
+func (nv *NetworkValidator) IdentifyNetworkError(err error) error {
+	if utils.IsNetworkError(err) {
 		if nv.offlineMode == "fail" {
 			return errors.New("Failed since internet connection refused, you can use the following command to set your config to run offline:\ndatree config set offline local")
 		}
diff --git a/pkg/utils/errors.go b/pkg/utils/errors.go
index 6ec0285..7368b5f 100644
--- a/pkg/utils/errors.go
+++ b/pkg/utils/errors.go
@@ -2,6 +2,7 @@ package utils
 
 import (
 	"fmt"
+	"net/url"
 	"strings"
 )
 
@@ -16,9 +17,9 @@ func ParseErrorToString(err interface{}) string {
 	}
 }
 
-func IsNetworkError(errStr string) bool {
+func IsNetworkError(err error) bool {
 	networkErrors := []string{"network error", "connection refused", "no such host", "i/o timeout", "server misbehaving"}
-	return stringInSliceContains(errStr, networkErrors)
+	return stringInSliceContains(err.Error(), networkErrors) || isUrlErrorType(err)
 }
 
 func stringInSliceContains(a string, list []string) bool {
@@ -29,3 +30,8 @@ func stringInSliceContains(a string, list []string) bool {
 	}
 	return false
 }
+
+func isUrlErrorType(err error) bool {
+	_, ok := err.(*url.Error)
+	return ok
+}


Test patch:
diff --git a/pkg/networkValidator/validator_test.go b/pkg/networkValidator/validator_test.go
index fbcebe4..606ecd2 100644
--- a/pkg/networkValidator/validator_test.go
+++ b/pkg/networkValidator/validator_test.go
@@ -1,6 +1,7 @@
 package networkValidator
 
 import (
+	"errors"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
@@ -58,20 +59,20 @@ func TestNetworkValidatorOtherError(t *testing.T) {
 
 func test_identifyNetworkError_network_error(validator *NetworkValidator, offlineMode string) error {
 	validator.SetOfflineMode(offlineMode)
-	return validator.IdentifyNetworkError("network error")
+	return validator.IdentifyNetworkError(errors.New("network error"))
 }
 
 func test_identifyNoInternet_noSuchHost_network_error(validator *NetworkValidator, offlineMode string) error {
 	validator.SetOfflineMode(offlineMode)
-	return validator.IdentifyNetworkError("no such host")
+	return validator.IdentifyNetworkError(errors.New("no such host"))
 }
 
 func test_identifyNoInternet_connectionRefused_network_error(validator *NetworkValidator, offlineMode string) error {
 	validator.SetOfflineMode(offlineMode)
-	return validator.IdentifyNetworkError("tcp dial connection refused")
+	return validator.IdentifyNetworkError(errors.New("tcp dial connection refused"))
 }
 
 func test_identifyNetworkError_other_error(validator *NetworkValidator, offlineMode string) error {
 	validator.SetOfflineMode(offlineMode)
-	return validator.IdentifyNetworkError("mysql server is away")
+	return validator.IdentifyNetworkError(errors.New("mysql server is away"))
 }