github.com/jghiloni/cli@v6.28.1-0.20170628223758-0ce05fe032a2+incompatible/api/cloudcontroller/ccv3/errors_test.go (about) 1 package ccv3_test 2 3 import ( 4 "net/http" 5 6 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 7 . "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 8 9 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/gomega" 11 . "github.com/onsi/gomega/ghttp" 12 ) 13 14 var _ = Describe("Error Wrapper", func() { 15 var ( 16 response string 17 serverResponseCode int 18 19 client *Client 20 ) 21 22 Describe("Make", func() { 23 BeforeEach(func() { 24 response = ` 25 { 26 "errors": [ 27 { 28 "code": 777, 29 "detail": "SomeCC Error Message", 30 "title": "CF-SomeError" 31 } 32 ] 33 }` 34 35 client = NewTestClient() 36 }) 37 38 JustBeforeEach(func() { 39 server.AppendHandlers( 40 CombineHandlers( 41 VerifyRequest(http.MethodGet, "/v3/apps"), 42 RespondWith(serverResponseCode, response, http.Header{ 43 "X-Vcap-Request-Id": { 44 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95", 45 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f", 46 }, 47 }, 48 ), 49 ), 50 ) 51 }) 52 53 Context("when the error is not from the cloud controller", func() { 54 Context("and the raw status is 404", func() { 55 BeforeEach(func() { 56 serverResponseCode = http.StatusNotFound 57 response = "some not found message" 58 }) 59 It("returns a NotFoundError", func() { 60 _, _, err := client.GetApplications(nil) 61 Expect(err).To(MatchError(ccerror.NotFoundError{Message: response})) 62 }) 63 }) 64 65 Context("and the raw status is another error", func() { 66 BeforeEach(func() { 67 serverResponseCode = http.StatusTeapot 68 response = "418 I'm a teapot: Requested route ('some-url.com') does not exist." 69 }) 70 It("returns a RawHTTPStatusError", func() { 71 _, _, err := client.GetApplications(nil) 72 Expect(err).To(MatchError(ccerror.RawHTTPStatusError{ 73 StatusCode: http.StatusTeapot, 74 RawResponse: []byte(response), 75 RequestIDs: []string{ 76 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95", 77 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f", 78 }, 79 })) 80 }) 81 }) 82 }) 83 84 Context("when the error is from the cloud controller", func() { 85 Context("when an empty list of errors is returned", func() { 86 BeforeEach(func() { 87 serverResponseCode = http.StatusUnauthorized 88 response = `{ "errors": [] }` 89 }) 90 91 It("returns an UnexpectedResponseError", func() { 92 _, _, err := client.GetApplications(nil) 93 Expect(err).To(MatchError(ccerror.V3UnexpectedResponseError{ 94 ResponseCode: http.StatusUnauthorized, 95 V3ErrorResponse: ccerror.V3ErrorResponse{Errors: []ccerror.V3Error{}}, 96 })) 97 }) 98 }) 99 100 Context("(401) Unauthorized", func() { 101 BeforeEach(func() { 102 serverResponseCode = http.StatusUnauthorized 103 }) 104 105 Context("generic 401", func() { 106 It("returns a UnauthorizedError", func() { 107 _, _, err := client.GetApplications(nil) 108 Expect(err).To(MatchError(ccerror.UnauthorizedError{Message: "SomeCC Error Message"})) 109 }) 110 }) 111 112 Context("invalid token", func() { 113 BeforeEach(func() { 114 response = `{ 115 "errors": [ 116 { 117 "code": 1000, 118 "detail": "Invalid Auth Token", 119 "title": "CF-InvalidAuthToken" 120 } 121 ] 122 }` 123 }) 124 125 It("returns an InvalidAuthTokenError", func() { 126 _, _, err := client.GetApplications(nil) 127 Expect(err).To(MatchError(ccerror.InvalidAuthTokenError{Message: "Invalid Auth Token"})) 128 }) 129 }) 130 }) 131 132 Context("(403) Forbidden", func() { 133 BeforeEach(func() { 134 serverResponseCode = http.StatusForbidden 135 }) 136 137 It("returns a ForbiddenError", func() { 138 _, _, err := client.GetApplications(nil) 139 Expect(err).To(MatchError(ccerror.ForbiddenError{Message: "SomeCC Error Message"})) 140 }) 141 }) 142 143 Context("(404) Not Found", func() { 144 BeforeEach(func() { 145 serverResponseCode = http.StatusNotFound 146 }) 147 148 It("returns a ResourceNotFoundError", func() { 149 _, _, err := client.GetApplications(nil) 150 Expect(err).To(MatchError(ccerror.ResourceNotFoundError{Message: "SomeCC Error Message"})) 151 }) 152 153 }) 154 155 Context("(422) Unprocessable Entity", func() { 156 BeforeEach(func() { 157 serverResponseCode = http.StatusUnprocessableEntity 158 }) 159 160 It("returns a UnprocessableEntityError", func() { 161 _, _, err := client.GetApplications(nil) 162 Expect(err).To(MatchError(ccerror.UnprocessableEntityError{Message: "SomeCC Error Message"})) 163 }) 164 }) 165 166 Context("(503) Service Unavailable", func() { 167 BeforeEach(func() { 168 serverResponseCode = http.StatusServiceUnavailable 169 }) 170 171 It("returns a ServiceUnavailableError", func() { 172 _, _, err := client.GetApplications(nil) 173 Expect(err).To(MatchError(ccerror.ServiceUnavailableError{Message: "SomeCC Error Message"})) 174 }) 175 176 Context("when the title is 'CF-TaskWorkersUnavailable'", func() { 177 BeforeEach(func() { 178 response = `{ 179 "errors": [ 180 { 181 "code": 170020, 182 "detail": "Task workers are unavailable: Failed to open TCP connection to nsync.service.cf.internal:8787 (getaddrinfo: Name or service not known)", 183 "title": "CF-TaskWorkersUnavailable" 184 } 185 ] 186 }` 187 }) 188 189 It("returns a TaskWorkersUnavailableError", func() { 190 _, _, err := client.GetApplications(nil) 191 Expect(err).To(MatchError(ccerror.TaskWorkersUnavailableError{Message: "Task workers are unavailable: Failed to open TCP connection to nsync.service.cf.internal:8787 (getaddrinfo: Name or service not known)"})) 192 }) 193 }) 194 }) 195 196 Context("Unhandled Error Codes", func() { 197 BeforeEach(func() { 198 serverResponseCode = http.StatusTeapot 199 }) 200 201 It("returns an UnexpectedResponseError", func() { 202 _, _, err := client.GetApplications(nil) 203 Expect(err).To(MatchError(ccerror.V3UnexpectedResponseError{ 204 ResponseCode: http.StatusTeapot, 205 V3ErrorResponse: ccerror.V3ErrorResponse{ 206 Errors: []ccerror.V3Error{ 207 { 208 Code: 777, 209 Detail: "SomeCC Error Message", 210 Title: "CF-SomeError", 211 }, 212 }, 213 }, 214 RequestIDs: []string{ 215 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95", 216 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f", 217 }, 218 })) 219 }) 220 }) 221 }) 222 }) 223 })