amazonka
amazonka copied to clipboard
Nullary response types don't get assigned a status code
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?
(to be clear, I'm testing ced0080dbf686b3bf90c5dd0fc984995f69f535a)
Thanks - looks like a silently failing XML deserialisation error, working on it now.
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
...
Related: #347 , but this is more far-reaching and may be better done post-2.0.