func unmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() if r.HTTPResponse.ContentLength == int64(0) { // No body, use status code to generate an awserr.Error r.Error = awserr.NewRequestFailure( awserr.New(strings.Replace(r.HTTPResponse.Status, " ", "", -1), r.HTTPResponse.Status, nil), r.HTTPResponse.StatusCode, "", ) return } resp := &xmlErrorResponse{} err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) if err != nil && err != io.EOF { r.Error = awserr.New("SerializationError", "failed to decode SimpleDB XML error response", nil) } else if len(resp.Errors) == 0 { r.Error = awserr.New("MissingError", "missing error code in SimpleDB XML error response", nil) } else { // If there are multiple error codes, return only the first as the aws.Error interface only supports // one error code. r.Error = awserr.NewRequestFailure( awserr.New(resp.Errors[0].Code, resp.Errors[0].Message, nil), r.HTTPResponse.StatusCode, resp.RequestID, ) } }
// UnmarshalError unmarshals an error response for a JSON RPC service. func UnmarshalError(req *service.Request) { defer req.HTTPResponse.Body.Close() bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body) if err != nil { req.Error = awserr.New("SerializationError", "failed reading JSON RPC error response", err) return } if len(bodyBytes) == 0 { req.Error = awserr.NewRequestFailure( awserr.New("SerializationError", req.HTTPResponse.Status, nil), req.HTTPResponse.StatusCode, "", ) return } var jsonErr jsonErrorResponse if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil { req.Error = awserr.New("SerializationError", "failed decoding JSON RPC error response", err) return } codes := strings.SplitN(jsonErr.Code, "#", 2) req.Error = awserr.NewRequestFailure( awserr.New(codes[len(codes)-1], jsonErr.Message, nil), req.HTTPResponse.StatusCode, "", ) }
// UnmarshalError unmarshals a response error for the REST JSON protocol. func UnmarshalError(r *request.Request) { code := r.HTTPResponse.Header.Get("X-Amzn-Errortype") bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "failed reading REST JSON error response", err) return } if len(bodyBytes) == 0 { r.Error = awserr.NewRequestFailure( awserr.New("SerializationError", r.HTTPResponse.Status, nil), r.HTTPResponse.StatusCode, "", ) return } var jsonErr jsonErrorResponse if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil { r.Error = awserr.New("SerializationError", "failed decoding REST JSON error response", err) return } if code == "" { code = jsonErr.Code } code = strings.SplitN(code, ":", 2)[0] r.Error = awserr.NewRequestFailure( awserr.New(code, jsonErr.Message, nil), r.HTTPResponse.StatusCode, r.RequestID, ) }
func unmarshalError(req *request.Request) { bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body) if err != nil { req.Error = awserr.New("UnmarshaleError", req.HTTPResponse.Status, err) return } if len(bodyBytes) == 0 { req.Error = awserr.NewRequestFailure( awserr.New("UnmarshaleError", req.HTTPResponse.Status, fmt.Errorf("empty body")), req.HTTPResponse.StatusCode, "", ) return } var jsonErr jsonErrorResponse if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil { req.Error = awserr.New("UnmarshaleError", "JSON unmarshal", err) return } req.Error = awserr.NewRequestFailure( awserr.New(jsonErr.Code, jsonErr.Message, nil), req.HTTPResponse.StatusCode, "", ) }
func serveTags(tags map[string]string) func(*request.Request) { return func(r *request.Request) { input, ok := r.Params.(*ec2.DescribeTagsInput) if !ok { r.Error = awserr.NewRequestFailure( awserr.New("UnknownError", "500 Internal Server Error", fmt.Errorf("unsupported request")), 500, "", ) return } restrictToKey := []*string{} for _, filter := range input.Filters { switch *filter.Name { case "resource-id": case "key": restrictToKey = filter.Values default: r.Error = awserr.NewRequestFailure( awserr.New("UnknownError", "500 Internal Server Error", fmt.Errorf("unsupported filter %s", *filter.Name)), 500, "", ) } } data := r.Data.(*ec2.DescribeTagsOutput) for key, value := range tags { if len(restrictToKey) > 0 && !includesString(restrictToKey, key) { continue } data.Tags = append(data.Tags, &ec2.TagDescription{Key: aws.String(key), Value: aws.String(value)}) } } }
func unmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() if r.HTTPResponse.StatusCode == http.StatusMovedPermanently { r.Error = awserr.New("BucketRegionError", fmt.Sprintf("incorrect region, the bucket is not in '%s' region", aws.StringValue(r.Service.Config.Region)), nil) return } if r.HTTPResponse.ContentLength == int64(0) { // No body, use status code to generate an awserr.Error r.Error = awserr.NewRequestFailure( awserr.New(strings.Replace(r.HTTPResponse.Status, " ", "", -1), r.HTTPResponse.Status, nil), r.HTTPResponse.StatusCode, "", ) return } resp := &xmlErrorResponse{} err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) if err != nil && err != io.EOF { r.Error = awserr.New("SerializationError", "failed to decode S3 XML error response", nil) } else { r.Error = awserr.NewRequestFailure( awserr.New(resp.Code, resp.Message, nil), r.HTTPResponse.StatusCode, "", ) } }
func unmarshalError(r *aws.Request) { defer r.HTTPResponse.Body.Close() if r.HTTPResponse.ContentLength == int64(0) { // No body, use status code to generate an awserr.Error r.Error = awserr.NewRequestFailure( awserr.New(strings.Replace(r.HTTPResponse.Status, " ", "", -1), r.HTTPResponse.Status, nil), r.HTTPResponse.StatusCode, "", ) return } resp := &xmlErrorResponse{} err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) if err != nil && err != io.EOF { r.Error = awserr.New("SerializationError", "failed to decode S3 XML error response", nil) } else { r.Error = awserr.NewRequestFailure( awserr.New(resp.Code, resp.Message, nil), r.HTTPResponse.StatusCode, "", ) } }
func unmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() defer io.Copy(ioutil.Discard, r.HTTPResponse.Body) // Bucket exists in a different region, and request needs // to be made to the correct region. if r.HTTPResponse.StatusCode == http.StatusMovedPermanently { r.Error = awserr.NewRequestFailure( awserr.New("BucketRegionError", fmt.Sprintf("incorrect region, the bucket is not in '%s' region", aws.StringValue(r.Config.Region)), nil), r.HTTPResponse.StatusCode, r.RequestID, ) return } var errCode, errMsg string // Attempt to parse error from body if it is known resp := &xmlErrorResponse{} err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) if err != nil && err != io.EOF { errCode = "SerializationError" errMsg = "failed to decode S3 XML error response" } else { errCode = resp.Code errMsg = resp.Message } // Fallback to status code converted to message if still no error code if len(errCode) == 0 { statusText := http.StatusText(r.HTTPResponse.StatusCode) errCode = strings.Replace(statusText, " ", "", -1) errMsg = statusText } r.Error = awserr.NewRequestFailure( awserr.New(errCode, errMsg, nil), r.HTTPResponse.StatusCode, r.RequestID, ) }
// UnmarshalError unmarshals an error response for an AWS Query service. func UnmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "failed to read from query HTTP response body", err) return } // First check for specific error resp := xmlErrorResponse{} decodeErr := xml.Unmarshal(bodyBytes, &resp) if decodeErr == nil { reqID := resp.RequestID if reqID == "" { reqID = r.RequestID } r.Error = awserr.NewRequestFailure( awserr.New(resp.Code, resp.Message, nil), r.HTTPResponse.StatusCode, reqID, ) return } // Check for unhandled error servUnavailResp := xmlServiceUnavailableResponse{} unavailErr := xml.Unmarshal(bodyBytes, &servUnavailResp) if unavailErr == nil { r.Error = awserr.NewRequestFailure( awserr.New("ServiceUnavailableException", "service is unavailable", nil), r.HTTPResponse.StatusCode, r.RequestID, ) return } // Failed to retrieve any error message from the response body r.Error = awserr.New("SerializationError", "failed to decode query XML error response", decodeErr) }
func TestTagsFs_OpenDir_error(t *testing.T) { client, dir, cleanup := setup(t) defer cleanup() client.Handlers.Send.PushBack(func(r *request.Request) { r.Error = awserr.NewRequestFailure( awserr.New("UnknownError", "500 Internal Server Error", fmt.Errorf("mock error")), 500, "", ) }) _, err := ioutil.ReadDir(path.Join(dir, "/")) if err.(*os.PathError).Err != syscall.EIO { t.Fatalf(`expected EIO, got %s`, err) } }
// UnmarshalError unmarshals a response error for the EC2 protocol. func UnmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() resp := &xmlErrorResponse{} err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) if err != nil && err != io.EOF { r.Error = awserr.New("SerializationError", "failed decoding EC2 Query error response", err) } else { r.Error = awserr.NewRequestFailure( awserr.New(resp.Code, resp.Message, nil), r.HTTPResponse.StatusCode, resp.RequestID, ) } }
func TestTagsFs_Open_error(t *testing.T) { client, dir, cleanup := setup(t) defer cleanup() numReqs := 0 client.Handlers.Send.PushBack(serveTags(map[string]string{"name": "MyName"})) client.Handlers.Send.PushBack(func(r *request.Request) { if numReqs == 0 { // Allow GetAttr call to succeed numReqs++ return } r.Error = awserr.NewRequestFailure( awserr.New("UnknownError", "500 Internal Server Error", fmt.Errorf("mock error")), 500, "", ) }) _, err := ioutil.ReadFile(path.Join(dir, "name")) if err.(*os.PathError).Err != syscall.EIO { t.Fatalf(`expected EIO, got %s`, err) } }
func unmarshalInvalidChangeBatchError(r *request.Request, requestBody []byte) { resp := &invalidChangeBatchXMLErrorResponse{} err := xml.Unmarshal(requestBody, resp) if err != nil { r.Error = awserr.New("SerializationError", "failed to decode query XML error response", err) return } const errorCode = "InvalidChangeBatch" errors := []error{} for _, msg := range resp.Messages { errors = append(errors, awserr.New(errorCode, msg, nil)) } r.Error = awserr.NewRequestFailure( awserr.NewBatchError(errorCode, "ChangeBatch errors occurred", errors), r.HTTPResponse.StatusCode, r.RequestID, ) }
Context("error cases", func() { Context("when an unknown command is provided", func() { It("prints usage and returns an error", func() { app = NewAppWithConfiguration(application.Configuration{ Command: "some-unknown-command", }) err := app.Run() Expect(err).To(MatchError("unknown command: some-unknown-command")) Expect(usage.PrintCall.CallCount).To(Equal(1)) }) }) Context("when the command fails for aws error", func() { It("returns an error and link to bbl README when error is AccessDenied", func() { awsError := awserr.New("UnauthorizedOperation", "User is not authorized to perform: action:SubCommand", nil) errorCmd.ExecuteCall.Returns.Error = awserr.NewRequestFailure(awsError, 403, "some-request-id") app = NewAppWithConfiguration(application.Configuration{ Command: "error", }) err := app.Run() Expect(err).To(MatchError("The AWS credentials provided have insufficient permissions to perform the operation `bbl error`.\nPlease refer to the bbl README:\nhttps://github.com/cloudfoundry/bosh-bootloader#configure-aws.\nOriginal error message from AWS:\n\nUser is not authorized to perform: action:SubCommand")) }) It("returns an error when the error is not AccessDenied", func() { awsError := awserr.New("InternalServerError", "Some message", nil) errorCmd.ExecuteCall.Returns.Error = awserr.NewRequestFailure(awsError, 500, "some-request-id") app = NewAppWithConfiguration(application.Configuration{ Command: "error", }) err := app.Run()
Context("and it is an AWS error", func() { BeforeEach(func() { describeStacksError = awserr.New("code", "message", errors.New("operation failed")) }) It("returns the proper error", func() { _, err := stack.Describe(stackName) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(Equal("code: message")) }) }) Context("and it is a 400 error", func() { BeforeEach(func() { awsError := awserr.New("code", "message", errors.New("operation failed")) describeStacksError = awserr.NewRequestFailure(awsError, 400, "request-id") }) It("returns the proper error", func() { _, err := stack.Describe(stackName) Expect(err).To(HaveOccurred()) Expect(err).To(Equal(ErrStackDoesNotExist)) }) }) }) }) var _ = Describe("Create", func() { var ( stackDetails StackDetails
Context("and it is an AWS error", func() { BeforeEach(func() { getQueueURLError = awserr.New("code", "message", errors.New("operation failed")) }) It("returns the proper error", func() { _, err := queue.Describe(queueName) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(Equal("code: message")) }) }) Context("and it is a 404 error", func() { BeforeEach(func() { awsError := awserr.New("code", "message", errors.New("operation failed")) getQueueURLError = awserr.NewRequestFailure(awsError, 404, "request-id") }) It("returns the proper error", func() { _, err := queue.Describe(queueName) Expect(err).To(HaveOccurred()) Expect(err).To(Equal(ErrQueueDoesNotExist)) }) }) }) Context("when getting the Queue Attibutes fails", func() { BeforeEach(func() { getQueueAttributesError = errors.New("operation failed") })
It("returns an error when the ServerCertificateMetadata is nil", func() { iamClient.GetServerCertificateCall.Returns.Output = &awsiam.GetServerCertificateOutput{ ServerCertificate: &awsiam.ServerCertificate{ ServerCertificateMetadata: nil, }, } _, err := describer.Describe("some-certificate") Expect(err).To(MatchError(iam.CertificateDescriptionFailure)) }) It("returns an error when the certificate cannot be described", func() { iamClient.GetServerCertificateCall.Returns.Error = awserr.NewRequestFailure( awserr.New("boom", "something bad happened", errors.New(""), ), 404, "0", ) _, err := describer.Describe("some-certificate") Expect(err).To(MatchError(ContainSubstring("something bad happened"))) }) It("returns a CertificateNotFound error when the certificate does not exist", func() { iamClient.GetServerCertificateCall.Returns.Error = awserr.NewRequestFailure( awserr.New("NoSuchEntity", "The Server Certificate with name some-certificate cannot be found.", errors.New(""), ), 404, "0", )
Context("and it is an AWS error", func() { BeforeEach(func() { describeDBClusterError = awserr.New("code", "message", errors.New("operation failed")) }) It("returns the proper error", func() { _, err := rdsDBCluster.Describe(dbClusterIdentifier) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(Equal("code: message")) }) }) Context("and it is a 404 error", func() { BeforeEach(func() { awsError := awserr.New("code", "message", errors.New("operation failed")) describeDBClusterError = awserr.NewRequestFailure(awsError, 404, "request-id") }) It("returns the proper error", func() { _, err := rdsDBCluster.Describe(dbClusterIdentifier) Expect(err).To(HaveOccurred()) Expect(err).To(Equal(ErrDBClusterDoesNotExist)) }) }) }) }) var _ = Describe("Create", func() { var ( dbClusterDetails DBClusterDetails
Context("and it is an AWS error", func() { BeforeEach(func() { describeDBInstanceError = awserr.New("code", "message", errors.New("operation failed")) }) It("returns the proper error", func() { _, err := rdsDBInstance.Describe(dbInstanceIdentifier) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(Equal("code: message")) }) }) Context("and it is a 404 error", func() { BeforeEach(func() { awsError := awserr.New("code", "message", errors.New("operation failed")) describeDBInstanceError = awserr.NewRequestFailure(awsError, 404, "request-id") }) It("returns the proper error", func() { _, err := rdsDBInstance.Describe(dbInstanceIdentifier) Expect(err).To(HaveOccurred()) Expect(err).To(Equal(ErrDBInstanceDoesNotExist)) }) }) }) }) var _ = Describe("Create", func() { var ( dbInstanceDetails DBInstanceDetails
Expect(cloudFormationClient.DescribeStacksCall.Receives.Input).To(Equal(&awscloudformation.DescribeStacksInput{ StackName: aws.String("some-stack-name"), })) Expect(stack).To(Equal(cloudformation.Stack{ Name: "some-stack-name", Status: "UPDATE_COMPLETE", Outputs: map[string]string{ "some-output-key": "some-output-value", }, })) }) Context("failure cases", func() { Context("when there is a response error", func() { It("returns an error when the RequestFailure response is not a 'StackNotFound'", func() { cloudFormationClient.DescribeStacksCall.Returns.Error = awserr.NewRequestFailure(awserr.New("ValidationError", "something bad happened", errors.New("")), 400, "0") _, err := manager.Describe("some-stack-name") Expect(err).To(MatchError(ContainSubstring("something bad happened"))) }) It("returns an error when the response is an unknown error", func() { cloudFormationClient.DescribeStacksCall.Returns.Error = errors.New("an unknown error occurred") _, err := manager.Describe("some-stack-name") Expect(err).To(MatchError(ContainSubstring("an unknown error occurred"))) }) }) Context("when stack output key or value is nil", func() { It("returns an error when the key in nil", func() { cloudFormationClient.DescribeStacksCall.Returns.Output = &awscloudformation.DescribeStacksOutput{ Stacks: []*awscloudformation.Stack{