github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/api/cloudcontroller/ccv2/errors_test.go (about) 1 package ccv2_test 2 3 import ( 4 "net/http" 5 6 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 7 . "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2" 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 serverResponse string 17 serverResponseCode int 18 19 client *Client 20 ) 21 22 Describe("Make", func() { 23 BeforeEach(func() { 24 serverResponse = `{ 25 "code": 777, 26 "description": "SomeCC Error Message", 27 "error_code": "CF-SomeError" 28 }` 29 30 client = NewTestClient() 31 }) 32 33 JustBeforeEach(func() { 34 server.AppendHandlers( 35 CombineHandlers( 36 VerifyRequest(http.MethodGet, "/v2/apps"), 37 RespondWith(serverResponseCode, serverResponse, http.Header{ 38 "X-Vcap-Request-Id": { 39 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95", 40 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f", 41 }, 42 }, 43 ), 44 ), 45 ) 46 }) 47 48 Context("when we can't unmarshal the response successfully", func() { 49 BeforeEach(func() { 50 serverResponse = "I am not unmarshallable" 51 serverResponseCode = http.StatusNotFound 52 }) 53 54 It("returns an unknown http source error", func() { 55 _, _, err := client.GetApplications() 56 Expect(err).To(MatchError(ccerror.UnknownHTTPSourceError{StatusCode: serverResponseCode, RawResponse: []byte(serverResponse)})) 57 }) 58 }) 59 60 Context("when the error is from the cloud controller", func() { 61 Context("when the error is a 4XX error", func() { 62 Context("(400) Bad Request", func() { 63 BeforeEach(func() { 64 serverResponseCode = http.StatusBadRequest 65 }) 66 67 Context("generic 400", func() { 68 BeforeEach(func() { 69 serverResponse = `{ 70 "description": "bad request", 71 "error_code": "CF-BadRequest" 72 }` 73 }) 74 75 It("returns a BadRequestError", func() { 76 _, _, err := client.GetApplications() 77 Expect(err).To(MatchError(ccerror.BadRequestError{ 78 Message: "bad request", 79 })) 80 }) 81 }) 82 83 Context("when a not staged error is encountered", func() { 84 BeforeEach(func() { 85 serverResponse = `{ 86 "description": "App has not finished staging", 87 "error_code": "CF-NotStaged" 88 }` 89 }) 90 91 It("returns a NotStagedError", func() { 92 _, _, err := client.GetApplications() 93 Expect(err).To(MatchError(ccerror.NotStagedError{ 94 Message: "App has not finished staging", 95 })) 96 }) 97 }) 98 99 Context("when an instances error is encountered", func() { 100 BeforeEach(func() { 101 serverResponse = `{ 102 "description": "instances went bananas", 103 "error_code": "CF-InstancesError" 104 }` 105 }) 106 107 It("returns an InstancesError", func() { 108 _, _, err := client.GetApplications() 109 Expect(err).To(MatchError(ccerror.InstancesError{ 110 Message: "instances went bananas", 111 })) 112 }) 113 }) 114 115 Context("when creating a relation that is invalid", func() { 116 BeforeEach(func() { 117 serverResponse = `{ 118 "code": 1002, 119 "description": "The requested app relation is invalid: the app and route must belong to the same space", 120 "error_code": "CF-InvalidRelation" 121 }` 122 }) 123 124 It("returns an InvalidRelationError", func() { 125 _, _, err := client.GetApplications() 126 Expect(err).To(MatchError(ccerror.InvalidRelationError{ 127 Message: "The requested app relation is invalid: the app and route must belong to the same space", 128 })) 129 }) 130 }) 131 132 Context("getting stats for a stopped app", func() { 133 BeforeEach(func() { 134 serverResponse = `{ 135 "code": 200003, 136 "description": "Could not fetch stats for stopped app: some-app", 137 "error_code": "CF-AppStoppedStatsError" 138 }` 139 }) 140 141 It("returns an AppStoppedStatsError", func() { 142 _, _, err := client.GetApplications() 143 Expect(err).To(MatchError(ccerror.ApplicationStoppedStatsError{ 144 Message: "Could not fetch stats for stopped app: some-app", 145 })) 146 }) 147 }) 148 }) 149 150 Context("(401) Unauthorized", func() { 151 BeforeEach(func() { 152 serverResponseCode = http.StatusUnauthorized 153 }) 154 155 Context("generic 401", func() { 156 It("returns a UnauthorizedError", func() { 157 _, _, err := client.GetApplications() 158 Expect(err).To(MatchError(ccerror.UnauthorizedError{Message: "SomeCC Error Message"})) 159 }) 160 }) 161 162 Context("invalid token", func() { 163 BeforeEach(func() { 164 serverResponse = `{ 165 "code": 1000, 166 "description": "Invalid Auth Token", 167 "error_code": "CF-InvalidAuthToken" 168 }` 169 }) 170 171 It("returns an InvalidAuthTokenError", func() { 172 _, _, err := client.GetApplications() 173 Expect(err).To(MatchError(ccerror.InvalidAuthTokenError{Message: "Invalid Auth Token"})) 174 }) 175 }) 176 }) 177 178 Context("(403) Forbidden", func() { 179 BeforeEach(func() { 180 serverResponseCode = http.StatusForbidden 181 }) 182 183 It("returns a ForbiddenError", func() { 184 _, _, err := client.GetApplications() 185 Expect(err).To(MatchError(ccerror.ForbiddenError{Message: "SomeCC Error Message"})) 186 }) 187 }) 188 189 Context("(404) Not Found", func() { 190 BeforeEach(func() { 191 serverResponseCode = http.StatusNotFound 192 }) 193 194 Context("when the error is a json response from the cloud controller", func() { 195 It("returns a ResourceNotFoundError", func() { 196 _, _, err := client.GetApplications() 197 Expect(err).To(MatchError(ccerror.ResourceNotFoundError{Message: "SomeCC Error Message"})) 198 }) 199 }) 200 }) 201 202 Context("(422) Unprocessable Entity", func() { 203 BeforeEach(func() { 204 serverResponseCode = http.StatusUnprocessableEntity 205 }) 206 207 It("returns a UnprocessableEntityError", func() { 208 _, _, err := client.GetApplications() 209 Expect(err).To(MatchError(ccerror.UnprocessableEntityError{Message: "SomeCC Error Message"})) 210 }) 211 }) 212 213 Context("unhandled Error Codes", func() { 214 BeforeEach(func() { 215 serverResponseCode = http.StatusTeapot 216 }) 217 218 It("returns an UnexpectedResponseError", func() { 219 _, _, err := client.GetApplications() 220 Expect(err).To(MatchError(ccerror.V2UnexpectedResponseError{ 221 ResponseCode: http.StatusTeapot, 222 V2ErrorResponse: ccerror.V2ErrorResponse{ 223 Code: 777, 224 Description: "SomeCC Error Message", 225 ErrorCode: "CF-SomeError", 226 }, 227 RequestIDs: []string{ 228 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95", 229 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f", 230 }, 231 })) 232 }) 233 }) 234 }) 235 236 Context("when the error is a 5XX error", func() { 237 BeforeEach(func() { 238 serverResponseCode = http.StatusBadGateway 239 serverResponse = "I am some text" 240 }) 241 242 It("returns a V2UnexpectedResponseError with no json", func() { 243 _, _, err := client.GetApplications() 244 Expect(err).To(MatchError(ccerror.V2UnexpectedResponseError{ 245 ResponseCode: http.StatusBadGateway, 246 V2ErrorResponse: ccerror.V2ErrorResponse{ 247 Description: serverResponse, 248 }, 249 RequestIDs: []string{ 250 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95", 251 "6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f", 252 }, 253 })) 254 }) 255 }) 256 }) 257 }) 258 })