github.com/dcarley/cf-cli@v6.24.1-0.20170220111324-4225ff346898+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" 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("UnexpectedResponseError", func() { 23 Describe("Error", func() { 24 It("returns all of the errors joined with newlines", func() { 25 err := UnexpectedResponseError{ 26 ResponseCode: http.StatusTeapot, 27 CCErrorResponse: CCErrorResponse{ 28 Errors: []CCError{ 29 { 30 Code: 282010, 31 Detail: "detail 1", 32 Title: "title-1", 33 }, 34 { 35 Code: 10242013, 36 Detail: "detail 2", 37 Title: "title-2", 38 }, 39 }, 40 }, 41 RequestIDs: []string{ 42 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95", 43 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f", 44 }, 45 } 46 47 Expect(err.Error()).To(Equal(`Unexpected Response 48 Response Code: 418 49 Request ID: 6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95 50 Request ID: 6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f 51 Code: 282010, Title: title-1, Detail: detail 1 52 Code: 10242013, Title: title-2, Detail: detail 2`)) 53 }) 54 }) 55 }) 56 57 Describe("Make", func() { 58 BeforeEach(func() { 59 response = ` 60 { 61 "errors": [ 62 { 63 "code": 777, 64 "detail": "SomeCC Error Message", 65 "title": "CF-SomeError" 66 } 67 ] 68 }` 69 70 client = NewTestClient() 71 }) 72 73 JustBeforeEach(func() { 74 server.AppendHandlers( 75 CombineHandlers( 76 VerifyRequest(http.MethodGet, "/v3/apps"), 77 RespondWith(serverResponseCode, response, http.Header{ 78 "X-Vcap-Request-Id": { 79 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95", 80 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f", 81 }, 82 }, 83 ), 84 ), 85 ) 86 }) 87 88 Context("when the error is not from the cloud controller", func() { 89 BeforeEach(func() { 90 serverResponseCode = http.StatusTeapot 91 response = "418 I'm a teapot: Requested route ('some-url.com') does not exist." 92 }) 93 94 It("returns a RawHTTPStatusError", func() { 95 _, _, err := client.GetApplications(nil) 96 Expect(err).To(MatchError(cloudcontroller.RawHTTPStatusError{ 97 StatusCode: http.StatusTeapot, 98 RawResponse: []byte(response), 99 RequestIDs: []string{ 100 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95", 101 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f", 102 }, 103 })) 104 }) 105 }) 106 107 Context("when the error is from the cloud controller", func() { 108 Context("when an empty list of errors is returned", func() { 109 BeforeEach(func() { 110 serverResponseCode = http.StatusUnauthorized 111 response = `{ "errors": [] }` 112 }) 113 114 It("returns an UnexpectedResponseError", func() { 115 _, _, err := client.GetApplications(nil) 116 Expect(err).To(MatchError(UnexpectedResponseError{ 117 ResponseCode: http.StatusUnauthorized, 118 CCErrorResponse: CCErrorResponse{Errors: []CCError{}}, 119 })) 120 }) 121 }) 122 123 Context("(401) Unauthorized", func() { 124 BeforeEach(func() { 125 serverResponseCode = http.StatusUnauthorized 126 }) 127 128 Context("generic 401", func() { 129 It("returns a UnauthorizedError", func() { 130 _, _, err := client.GetApplications(nil) 131 Expect(err).To(MatchError(cloudcontroller.UnauthorizedError{Message: "SomeCC Error Message"})) 132 }) 133 }) 134 135 Context("invalid token", func() { 136 BeforeEach(func() { 137 response = `{ 138 "errors": [ 139 { 140 "code": 1000, 141 "detail": "Invalid Auth Token", 142 "title": "CF-InvalidAuthToken" 143 } 144 ] 145 }` 146 }) 147 148 It("returns an InvalidAuthTokenError", func() { 149 _, _, err := client.GetApplications(nil) 150 Expect(err).To(MatchError(cloudcontroller.InvalidAuthTokenError{Message: "Invalid Auth Token"})) 151 }) 152 }) 153 }) 154 155 Context("(403) Forbidden", func() { 156 BeforeEach(func() { 157 serverResponseCode = http.StatusForbidden 158 }) 159 160 It("returns a ForbiddenError", func() { 161 _, _, err := client.GetApplications(nil) 162 Expect(err).To(MatchError(cloudcontroller.ForbiddenError{Message: "SomeCC Error Message"})) 163 }) 164 }) 165 166 Context("(404) Not Found", func() { 167 BeforeEach(func() { 168 serverResponseCode = http.StatusNotFound 169 }) 170 171 It("returns a ResourceNotFoundError", func() { 172 _, _, err := client.GetApplications(nil) 173 Expect(err).To(MatchError(cloudcontroller.ResourceNotFoundError{Message: "SomeCC Error Message"})) 174 }) 175 176 Context("when the error is not from the cloud controller API", func() { 177 BeforeEach(func() { 178 response = "an error not from the CC API" 179 }) 180 181 It("returns a NotFoundError", func() { 182 _, _, err := client.GetApplications(nil) 183 Expect(err).To(MatchError(cloudcontroller.NotFoundError{Message: response})) 184 }) 185 }) 186 }) 187 188 Context("(422) Unprocessable Entity", func() { 189 BeforeEach(func() { 190 serverResponseCode = http.StatusUnprocessableEntity 191 }) 192 193 It("returns a UnprocessableEntityError", func() { 194 _, _, err := client.GetApplications(nil) 195 Expect(err).To(MatchError(cloudcontroller.UnprocessableEntityError{Message: "SomeCC Error Message"})) 196 }) 197 }) 198 199 Context("(503) Service Unavailable", func() { 200 BeforeEach(func() { 201 serverResponseCode = http.StatusServiceUnavailable 202 }) 203 204 It("returns a ServiceUnavailableError", func() { 205 _, _, err := client.GetApplications(nil) 206 Expect(err).To(MatchError(cloudcontroller.ServiceUnavailableError{Message: "SomeCC Error Message"})) 207 }) 208 209 Context("when the title is 'CF-TaskWorkersUnavailable'", func() { 210 BeforeEach(func() { 211 response = `{ 212 "errors": [ 213 { 214 "code": 170020, 215 "detail": "Task workers are unavailable: Failed to open TCP connection to nsync.service.cf.internal:8787 (getaddrinfo: Name or service not known)", 216 "title": "CF-TaskWorkersUnavailable" 217 } 218 ] 219 }` 220 }) 221 222 It("returns a TaskWorkersUnavailableError", func() { 223 _, _, err := client.GetApplications(nil) 224 Expect(err).To(MatchError(TaskWorkersUnavailableError{Message: "Task workers are unavailable: Failed to open TCP connection to nsync.service.cf.internal:8787 (getaddrinfo: Name or service not known)"})) 225 }) 226 }) 227 }) 228 229 Context("Unhandled Error Codes", func() { 230 BeforeEach(func() { 231 serverResponseCode = http.StatusTeapot 232 }) 233 234 It("returns an UnexpectedResponseError", func() { 235 _, _, err := client.GetApplications(nil) 236 Expect(err).To(MatchError(UnexpectedResponseError{ 237 ResponseCode: http.StatusTeapot, 238 CCErrorResponse: CCErrorResponse{ 239 Errors: []CCError{ 240 { 241 Code: 777, 242 Detail: "SomeCC Error Message", 243 Title: "CF-SomeError", 244 }, 245 }, 246 }, 247 RequestIDs: []string{ 248 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95", 249 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f", 250 }, 251 })) 252 }) 253 }) 254 }) 255 }) 256 })