amazonka icon indicating copy to clipboard operation
amazonka copied to clipboard

Nullary response types don't get assigned a status code

Open brendanhay opened this issue 9 years ago • 5 comments

brendanhay avatar Aug 19 '15 07:08 brendanhay

I think it also applies to errors for calls like AttachVolume (Rs a ~ VolumeAttachment):

[Client Request] {
  host    = ec2.ap-southeast-1.amazonaws.com
  port    = 443
  secure  = True
  headers = host: ec2.ap-southeast-1.amazonaws.com; x-amz-date: 20150819T105121Z; x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855; authorization: AWS4-HMAC-SHA256 Credential=LALALA/20150819/ap-southeast-1/ec2/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=fb2359c3301ee3e12233ffa766c913b5f04e405b887081fb7f59d2c7006415c3
  path    = /
  query   = ?Action=AttachVolume&Device=%2Fdev%2Fxvdm&InstanceId=i-977d635b&Version=2015-04-15&VolumeId=vol-8c8cea98
  method  = POST
  timeout = Just 70000000
}
[Client Response] {
  status  = 400 Bad Request
  version = HTTP/1.1
  headers = transfer-encoding: chunked; date: Wed, 19 Aug 2015 10:51:22 GMT; nncoection: close; server: AmazonEC2
  cookies = CJ {expose = []}
}

The response body is:

<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Response><Errors><Error><Code>VolumeInUse</Code><Message>vol-8c8cea98 is already attached to an instance</Message></Error></Errors><RequestID>c0ca7700-c515-4653-87e3-f1a9ce6416e8</RequestID></Response>

The error is:

ServiceError (ServiceError' {_serviceAbbrev = Abbrev "EC2", _serviceStatus = Status {statusCode = 400, statusMessage = "Bad Request"}, _serviceHeaders = [("Transfer-Encoding","chunked"),("Date","Wed, 19 Aug 2015 10:51:22 GMT"),("nnCoection","close"),("Server","AmazonEC2")],
_serviceCode = ErrorCode "Bad Request", _serviceMessage = Nothing, _serviceRequestId = Nothing})

(I expected to see VolumeInUse instead of BadRequest). Unless I'm misusing the API?

proger avatar Aug 19 '15 10:08 proger

(to be clear, I'm testing ced0080dbf686b3bf90c5dd0fc984995f69f535a)

proger avatar Aug 19 '15 11:08 proger

Thanks - looks like a silently failing XML deserialisation error, working on it now.

brendanhay avatar Aug 19 '15 11:08 brendanhay

So the original issue is fixable, attaching an error code to the nullary response is just a case of substituting nullary responses for records with a single status field during generation.

The 'shared' responses, that is, those types that are actually members of the Network.AWS.<Service>.Types namespace and not local to the operation, cannot be modified to carry around the status without potentially affecting other usages of such types. ie. I don't really want to attach an extraneous 'status' field to VolumeAttachment if it is used outside the domain of responses.

The fix seems to be to introduce another layer, potentially for all respones:

data Response a = Response
    { _rsStatus :: Int
    , _rsHeaders :: [Header]
    , _rsWhatever :: Whatever -- ^ http://www.dailymotion.com/video/x1f4z_liam-lynch-united-states-of-whateve_music
    , _rsShape :: a
    }

The exposed lenses for each operation wouldn't change, they transparently pass through the above Response type:

someResponseLens :: Lens' (Response DescribeInstances) [Reservation]
someResponseLens = rsShape . lens _dirsReservations (\s a -> s { _dirsReservations = a })

And you end up with the AWSRequest instance's associated Rs type synonym for the response looking like:

instance AWSRequest DescribeInstances where
    type Sv DescribeInstances = EC2
    type Rs DescribeInstances = Response DescribeInstancesResponse
    ...  

brendanhay avatar Aug 19 '15 16:08 brendanhay

Related: #347 , but this is more far-reaching and may be better done post-2.0.

endgame avatar Oct 04 '21 02:10 endgame