Throw up a red bar on /attempt timeout of 30 seconds

Summary:
If we don't receive a response to `/attempt` within 30 seconds, we
throw up an error (the red bar) and prevent the user from
continuing. Why do we timeout requests? Dropped requests seem to be
a real thing and causes problems. First, a dropped request is bad by
itself, but also prevents any future requests from being sent
because we queue up requests on the client. Also, before we render
the end-of-task card, we wait for all requests to return, and if
there's a dropped request, we throw up a spinner that spins forever.
This is a real problem that we were first made aware of from iPad
Safari users in classrooms. We also added logging after 60 seconds
of waiting for all requests to return at the pre-end-of-task card
spinner, and it occurs frequently (several times every minute). (See D12825)
Though it would be good to retry requests, that's going to be
slightly tricker to do to ensure the server can be idempotent or be
able to handle multiple requests. So for now, we are just showing
the red error bar, which, although jarring, is hopefully less bad
than being stuck with an endless spinner before the end of task
card and then losing all progress since the first dropped request.

This change was motivated by our attempts to debug the ipad safari endless
spinner before end of task card bug. See more details here:
https://trello.com/c/5vwntenP/1651-debug-endless-spinner-at-end-of-task-card-on-ipad-web

Is 30 seconds reasonable? I feel like a minute might be a bit too long to make
users wait before throwing up an error (they may have already done some more
problems and that progress would be lost), but less than 30 seconds also feels
it might not be long enough? If you have thoughts let me know. We can of course
adjust this threshold depending on the volume of logs we see.

Hopefully, with this change, we'll see less of those `/sendtolog` requests that
are due to the 60-second time out at end of task card spinner.

Test Plan:
- temporarily changed `REQUEST_TIMEOUT_MS` to be 3 ms
- answered a problem
- immediately saw the red bar appear
- clicked the links to make sure they work
- saw that refreshing takes us back to the problem on which we got the timed out request
- clicked a hint this time
- saw no red bar (we don't warn on /hint request errors at the moment. But this
  change still applies the 30-second timeout to /hint requests, so after 30
  seconcds we'll silently fail the /hint requests but trigger `apiRequestEnded`
  which will decrement the outstanding requests count, thus not leading to
  infinite spinner)
- changed `REQUEST_TIMEOUT_MS` back to 30 seconds and completed an exercise

Reviewers: alpert, ben, benkomalo

Reviewed By: benkomalo

Subscribers: jessie

Differential Revision: http://phabricator.khanacademy.org/D13121