diff --git a/auth/auth_test.go b/auth/auth_test.go index e1de803..ecb90d1 100644 --- a/auth/auth_test.go +++ b/auth/auth_test.go @@ -1,12 +1,10 @@ package auth import ( - "errors" "fmt" "io/ioutil" "net/http" "net/http/httptest" - "reflect" "testing" deis "github.com/deis/controller-sdk-go" @@ -247,17 +245,16 @@ func TestDeleteUserApp(t *testing.T) { server := httptest.NewServer(&handler) defer server.Close() - deis, err := deis.New(false, server.URL, "abc", "") + d, err := deis.New(false, server.URL, "abc", "") if err != nil { t.Fatal(err) } - err = Delete(deis, "admin") + err = Delete(d, "admin") // should be a 409 Conflict - expected := errors.New("409 Conflict") - if reflect.DeepEqual(err, expected) == false { - t.Errorf("got '%s' but expected '%s'", err, expected) + if err != deis.ErrConflict { + t.Errorf("got '%s' but expected '%s'", err, deis.ErrConflict) } } diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..f56b218 --- /dev/null +++ b/errors.go @@ -0,0 +1,208 @@ +package deis + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + "strings" +) + +const ( + // formatErrUnknown is used to create an dynamic error if no error matches + formatErrUnknown = "Unknown Error (%d): %s" + // fieldReqMsg is API error stating a field is required. + fieldReqMsg = "This field is required." + invalidUserMsg = "Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters." + failedLoginMsg = "Unable to log in with provided credentials." + invalidAppNameMsg = "App name can only contain a-z (lowercase), 0-9 and hypens" + invalidNameMsg = "Can only contain a-z (lowercase), 0-9 and hypens" + invalidCertMsg = "Could not load certificate" + invalidPodMsg = "does not exist in application" + invalidDomainMsg = "Hostname does not look valid." + invalidVersionMsg = "version cannot be below 0" + invalidKeyMsg = "Key contains invalid base64 chars" +) + +var ( + // ErrNotFound is returned when the server returns a 404. + ErrNotFound = errors.New("Not Found") + // ErrServerError is returned when the server returns a 500. + ErrServerError = errors.New("Internal Server Error") + // ErrMethodNotAllowed is thrown when using a unsupposrted method. + // This should not come up unless there in an bug in the SDK. + ErrMethodNotAllowed = errors.New("Method Not Allowed") + // ErrInvalidUsername is returned when the user specifies an invalid or missing username. + ErrInvalidUsername = errors.New(invalidUserMsg) + // ErrMissingPassword is returned when a password is not sent with the request. + ErrMissingPassword = errors.New("A Password is required") + // ErrLogin is returned when the api cannot login fails with provided username and password + ErrLogin = errors.New(failedLoginMsg) + // ErrUnauthorized is given when the API returns a 401. + ErrUnauthorized = errors.New("Unauthorized: Missing or Invalid Token") + // ErrInvalidAppName is returned when the user specifies an invalid app name. + ErrInvalidAppName = errors.New(invalidAppNameMsg) + // ErrConflict is returned when the API returns a 409. + ErrConflict = errors.New("This action could not be completed due to a conflict.") + // ErrForbidden is returned when the API returns a 403. + ErrForbidden = errors.New("You do not have permission to perform this action.") + // ErrMissingKey is returned when a key is not sent with the request. + ErrMissingKey = errors.New("A key is required") + // ErrInvalidName is returned when a name is invalid or missing. + ErrInvalidName = errors.New(invalidNameMsg) + // ErrInvalidCertificate is returned when a certififate is missing or invalid + ErrInvalidCertificate = errors.New(invalidCertMsg) + // ErrPodNotFound is returned when a pod type is not Found + ErrPodNotFound = errors.New("Pod not found in application") + // ErrInvalidDomain is returned when a domain is missing or invalid + ErrInvalidDomain = errors.New(invalidDomainMsg) + // ErrInvalidImage is returned when a image is missing or invalid + ErrInvalidImage = errors.New("The given image is invalid") + // ErrInvalidVersion is returned when a version is invalid + ErrInvalidVersion = errors.New("The given version is invalid") + // ErrMissingID is returned when a ID is missing + ErrMissingID = errors.New("An id is required") +) + +func checkForErrors(res *http.Response) error { + if res.StatusCode >= 200 && res.StatusCode < 400 { + return nil + } + + // Fix json.Decoder bug in 199 && res.StatusCode < 400 { - return nil - } - - // TEMPORARY: Close body because methods won't close it (for now) because - // they can't tell the difference between an HTTP error and a bad status code - // (which has a body to close) - res.Body.Close() - - //TODO: Implement better error system! - return errors.New(res.Status) -} - // CheckConnection checks that the user is connected to a network and the URL points to a valid controller. func (c *Client) CheckConnection() error { errorMessage := `%s does not appear to be a valid Deis controller. diff --git a/http_test.go b/http_test.go index 69feaa5..3e0b28a 100644 --- a/http_test.go +++ b/http_test.go @@ -168,28 +168,6 @@ func TestBasicRequest(t *testing.T) { } } -func TestCheckErrorsReturnsNil(t *testing.T) { - t.Parallel() - - responses := []http.Response{ - { - StatusCode: http.StatusOK, - }, - { - StatusCode: http.StatusCreated, - }, - { - StatusCode: http.StatusNoContent, - }, - } - - for _, res := range responses { - if err := checkForErrors(&res); err != nil { - t.Fatal(err) - } - } -} - func TestLimitedRequest(t *testing.T) { t.Parallel()