@@ -13,21 +13,26 @@ import (
1313const (
1414 // formatErrUnknown is used to create an dynamic error if no error matches
1515 formatErrUnknown = "Unknown Error (%d): %s"
16+ jsonParsingError = "error decoding json response (%s): %s"
17+
1618 // fieldReqMsg is API error stating a field is required.
17- fieldReqMsg = "This field is required."
18- invalidUserMsg = "Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters."
19- failedLoginMsg = "Unable to log in with provided credentials."
20- invalidAppNameMsg = "App name can only contain a-z (lowercase), 0-9 and hyphens"
21- invalidNameMsg = "Can only contain a-z (lowercase), 0-9 and hyphens"
22- invalidCertMsg = "Could not load certificate"
23- invalidPodMsg = "does not exist in application"
24- invalidDomainMsg = "Hostname does not look valid."
25- invalidVersionMsg = "version cannot be below 0"
26- invalidKeyMsg = "Key contains invalid base64 chars"
27- duplicateUserMsg = "A user with that username already exists."
28- invalidEmailMsg = "Enter a valid email address."
29- invalidTagMsg = "No nodes matched the provided labels"
30- duplicateIDMsg = "App with this id already exists."
19+ fieldReqMsg = "This field is required."
20+ invalidUserMsg = "Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters."
21+ failedLoginMsg = "Unable to log in with provided credentials."
22+ invalidAppNameMsg = "App name can only contain a-z (lowercase), 0-9 and hyphens"
23+ invalidNameMsg = "Can only contain a-z (lowercase), 0-9 and hyphens"
24+ invalidCertMsg = "Could not load certificate"
25+ invalidPodMsg = "does not exist in application"
26+ invalidDomainMsg = "Hostname does not look valid."
27+ invalidVersionMsg = "version cannot be below 0"
28+ invalidKeyMsg = "Key contains invalid base64 chars"
29+ duplicateUserMsg = "A user with that username already exists."
30+ invalidEmailMsg = "Enter a valid email address."
31+ invalidTagMsg = "No nodes matched the provided labels"
32+ duplicateIDMsg = "App with this id already exists."
33+ cancellationFailedMsg = "still has applications assigned. Delete or transfer ownership"
34+ duplicateDomainMsg = "Domain is already in use by another application"
35+ duplicateKeyMsg = "Public Key is already in use"
3136)
3237
3338var (
5661 ErrForbidden = errors .New ("You do not have permission to perform this action." )
5762 // ErrMissingKey is returned when a key is not sent with the request.
5863 ErrMissingKey = errors .New ("A key is required" )
64+ // ErrDuplicateKey is returned when adding a key that already exists.
65+ ErrDuplicateKey = errors .New (duplicateKeyMsg )
5966 // ErrInvalidName is returned when a name is invalid or missing.
6067 ErrInvalidName = errors .New (invalidNameMsg )
6168 // ErrInvalidCertificate is returned when a certififate is missing or invalid
6471 ErrPodNotFound = errors .New ("Pod not found in application" )
6572 // ErrInvalidDomain is returned when a domain is missing or invalid
6673 ErrInvalidDomain = errors .New (invalidDomainMsg )
74+ // ErrDuplicateDomain is returned adding domain that is already in use
75+ ErrDuplicateDomain = errors .New (duplicateDomainMsg )
6776 // ErrInvalidImage is returned when a image is missing or invalid
6877 ErrInvalidImage = errors .New ("The given image is invalid" )
6978 // ErrInvalidVersion is returned when a version is invalid
7887 ErrDuplicateApp = errors .New (duplicateIDMsg )
7988 // ErrUnprocessable is returned when the controller throws a 422.
8089 ErrUnprocessable = errors .New ("Unable to process your request." )
90+ // ErrCancellationFailed is returned when cancelling a user fails.
91+ ErrCancellationFailed = errors .New ("Failed to delete user because the user still has applications assigned. Delete or transfer ownership." )
8192)
8293
8394// checkForErrors tries to match up an API error with an predefined error in the SDK.
@@ -101,7 +112,7 @@ func checkForErrors(res *http.Response) error {
101112 case 400 :
102113 bodyMap := make (map [string ]interface {})
103114 if err := json .Unmarshal (out , & bodyMap ); err != nil {
104- return unknownServerError (res .StatusCode , fmt .Sprintf ("error decoding json response (%s): %s" , err , string (out )))
115+ return unknownServerError (res .StatusCode , fmt .Sprintf (jsonParsingError , err , string (out )))
105116 }
106117
107118 if scanResponse (bodyMap , "username" , []string {fieldReqMsg , invalidUserMsg }, true ) {
@@ -132,6 +143,10 @@ func checkForErrors(res *http.Response) error {
132143 return ErrMissingKey
133144 }
134145
146+ if scanResponse (bodyMap , "key" , []string {duplicateKeyMsg }, true ) {
147+ return ErrDuplicateKey
148+ }
149+
135150 if scanResponse (bodyMap , "public" , []string {fieldReqMsg , invalidKeyMsg }, true ) {
136151 return ErrMissingKey
137152 }
@@ -148,6 +163,10 @@ func checkForErrors(res *http.Response) error {
148163 return ErrInvalidDomain
149164 }
150165
166+ if scanResponse (bodyMap , "domain" , []string {duplicateDomainMsg }, true ) {
167+ return ErrDuplicateDomain
168+ }
169+
151170 if scanResponse (bodyMap , "image" , []string {fieldReqMsg }, true ) {
152171 return ErrInvalidImage
153172 }
@@ -181,7 +200,16 @@ func checkForErrors(res *http.Response) error {
181200 case 405 :
182201 return ErrMethodNotAllowed
183202 case 409 :
184- return ErrConflict
203+ bodyMap := make (map [string ]interface {})
204+ if err := json .Unmarshal (out , & bodyMap ); err != nil {
205+ return unknownServerError (res .StatusCode , fmt .Sprintf (jsonParsingError , err , string (out )))
206+ }
207+ if v , ok := bodyMap ["detail" ].(string ); ok {
208+ if strings .Contains (v , cancellationFailedMsg ) {
209+ return ErrCancellationFailed
210+ }
211+ }
212+ return unknownServerError (res .StatusCode , string (out ))
185213 case 422 :
186214 return ErrUnprocessable
187215 case 500 :
0 commit comments