aws

http://status.aws.amazon.com/ https://www.expeditedssl.com/aws-in-plain-english
kenny 2020-03-09T21:58:24.097600Z

is "Throttling" represented as an http status code, or only within [:ErrorResponse :Error :Code]) ?@ghadi You asked the above. Throttling is only represented via that path. Here's a simple example:

(def c (aws-api/client {:api :workspaces}))
(def results
  (vec (pmap (fn [_]
               (aws-api/invoke c {:op :DescribeWorkspaceDirectories}))
             (range 20))))

(first (filter anom/anomaly? results))
=>
{:__type "ThrottlingException", :message "Rate exceeded", :cognitect.anomalies/category :cognitect.anomalies/incorrect}

(get-in (meta *1) [:http-response :status])
=> 400

ghadi 2020-03-09T21:58:51.098100Z

do you have the complete response headers?

kenny 2020-03-09T21:58:55.098300Z

Yes

kenny 2020-03-09T21:59:28.098800Z

{"x-amz-date" "20200309T215544Z",
 "x-amz-target" "WorkspacesService.DescribeWorkspaceDirectories",
 "content-type" "application/x-amz-json-1.1",
 "host" "<http://workspaces.us-west-2.amazonaws.com|workspaces.us-west-2.amazonaws.com>",
 "authorization" "..."}

ghadi 2020-03-09T21:59:45.099400Z

that's the response?

ghadi 2020-03-09T22:00:03.100200Z

seems like the request

kenny 2020-03-09T22:00:03.100300Z

Headers

kenny 2020-03-09T22:00:09.100500Z

Oops, yeah

kenny 2020-03-09T22:00:18.100900Z

{"x-amzn-requestid" "59bbfe02-e3b0-49fa-a2cb-2027a236531a",
 "connection" "close",
 "content-length" "58",
 "date" "Mon, 09 Mar 2020 21:55:44 GMT",
 "content-type" "application/x-amz-json-1.1"}

kenny 2020-03-09T22:00:56.101800Z

We also have to use this for :retriable? for the apis we use.

(def api-&gt;retriable-fn
  "Map of AWS API to a fn that will be called to see if the request should be retried
  based on the HTTP response. This is needed because various AWS APIs indicate
  failures in non-standard ways."
  {:workspaces #(= "ThrottlingException" (:__type %))
   :pricing    #(= "ThrottlingException" (:__type %))
   :monitoring #(= "Throttling" (get-in % [:ErrorResponse :Error :Code]))})

ghadi 2020-03-09T22:01:05.102Z

what else is in the json response?

ghadi 2020-03-09T22:01:31.102500Z

I'm trying to see if there is something generic we can detect and return a :busy anomaly

kenny 2020-03-09T22:01:39.102800Z

The body is this: {:type "ThrottlingException", :message "Rate exceeded", :cognitect.anomalies/category :cognitect.anomalies/incorrect}

kenny 2020-03-09T22:01:51.103300Z

From my experience, I don't think there is 😞

ghadi 2020-03-09T22:01:52.103400Z

what about the raw response JSON?

kenny 2020-03-09T22:02:04.103800Z

Just slurping the :body?

ghadi 2020-03-09T22:02:14.104100Z

yeah, should be available

kenny 2020-03-09T22:02:32.104400Z

(slurp (:body (:http-response (meta (first (filter anom/anomaly? results))))))
=&gt; "{\"__type\":\"ThrottlingException\",\"message\":\"Rate exceeded\"}"

ghadi 2020-03-09T22:02:45.104600Z

Thanks AWS™

kenny 2020-03-09T22:03:42.105600Z

Yep... It's frustrating. The above retry works but it results in incorrect anomalies getting returned. In the above example, it returns incorrect when it should be busy.

ghadi 2020-03-09T22:04:18.105900Z

should really send back a status 429

kenny 2020-03-09T22:04:36.106400Z

Agreed. This happens in several of their apis though.

ghadi 2020-03-09T22:04:43.106600Z

yeah

ghadi 2020-03-09T22:06:17.107700Z

@dchelimsky do we read :errors from the descriptors?

2020-03-09T22:07:33.108500Z

Not yet. We looked at it as a means of normalizing error handling, but there is nothing normalizable (every service does its own thing).

2020-03-09T22:12:48.110100Z

Also, I ran into a few cases in which the descriptors themselves listed error shapes in operation maps, but those weren't present in the shapes map.

2020-03-09T22:13:37.110900Z

@ghadi @kenny am I missing some value we'd get from reading them anyway?

ghadi 2020-03-09T22:14:15.111500Z

just need to be able to dispatch on the error shape name

ghadi 2020-03-09T22:14:29.111900Z

is that always in __type?

ghadi 2020-03-09T22:14:44.112700Z

we can't generically understand the errors without a lookup table

2020-03-09T22:14:46.112900Z

That's only a thing in some json services.

✔️ 2
2020-03-09T22:15:04.113500Z

There is no spec for this @ghadi

2020-03-09T22:15:13.114Z

No consistency across services.

ghadi 2020-03-09T22:15:13.114300Z

right.

2020-03-09T22:15:38.115100Z

The error shape name is in the operation, which is already part of the model we use.

ghadi 2020-03-09T22:16:02.115800Z

error shape name is useful enough

2020-03-09T22:16:15.116300Z

I think that should be in (ops client)

2020-03-09T22:16:29.116700Z

(don't have a repl up for this at the moment)

ghadi 2020-03-09T22:17:06.117400Z

the ThrottlingException @kenny encountered isn't even in the workspaces service descriptor :)

😞 1
2020-03-09T22:17:17.117700Z

That's what I'm talking about 😕

2020-03-09T22:18:12.118600Z

Can't exactly knock AWS for this. Nobody said "hey, use these descriptors to build your own SDKs" 😉

kenny 2020-03-09T22:18:43.119Z

They should return standard http status codes though

ghadi 2020-03-09T22:19:35.120Z

it doesn't say s* about how those errors are encoded on the wire

2020-03-09T22:20:06.120500Z

Can't break promises you don't make!

2020-03-09T22:21:46.120900Z

This all came up recently, btw: https://github.com/cognitect-labs/aws-api/issues/123

kenny 2020-03-09T22:25:42.122900Z

Having the ability to manually transform response bodies before the :retriable? call would help us in this situation. The transformed response would also need to be returned to the caller. I realize it's not a general solution, but it's sounding like there is not one.

2020-03-09T22:36:48.123900Z

Please feel free to make suggestions there in comments.

1
kenny 2020-03-09T22:53:54.128100Z

On a totally unrelated note, @ghadi you may recall I brought up the issue of an AWS API returning an invalid next-token. After a month or so, I finally got it again! Unfortunately the code to log the request-id had a typo in the key to lookup so I didn't get a request-id from the failure 😞 The next-token looks totally standard for this API. The system retrying the same call ~30s later and it worked. Quite odd behavior. Wonder if AWS has some sort of race condition.

{:__type "InvalidParameterValuesException",
 :message "Invalid NextToken provided.",
 :cognitect.anomalies/category :cognitect.anomalies/incorrect,
 :next-token "af286f1d-36ac-4fd2-bd5a-fa79fbb72f4b",
 :page-count 4}

kenny 2020-03-09T22:54:38.128200Z

I am determined to get AWS to fix this issue. Hopefully next time this error occurs I'll have a request id for them to debug this!