Add a catch-all for timeout exceptions

While trying to write a 170MB file into GCS on a managed VM, I encountered the exception shown below. This is nearly identical to the problem I describe in https://github.com/Khan/appengine-gcs-client/commit/482cb207cb960013e6fcad8a07c52ce6b3d2d993. I searched around the SDK code a bit and saw that the `requests` library has a `ConnectionError`, so my initial attempt at resolving this was to add `requests.ConnectionError` and `requests.exceptions.ConnectionError` to the list of retriable exceptions, like I did with the previous change. This did not actually fix things, so then I added the catch-all logging statement to storage_api.py so I could see the type of the exception that was being raised. The type that statement showed me was a rather mysterious `request_nologs.exceptions.ConnectionError`. I tried adding this to the list of retriable exceptions, but since I don't have a library with that name installed locally it failed to import (obviously). It seems like the managed VMs are using a custom renamed build of the requests library. Instead of digging to the bottom of that hole, I just added a more generic catch-all to the retry loop in api_utils.py. This catch-all allows retrying when the exception message contains `timeout`. I hit another oddity here where the `str(e)` (and also `e.message`) were a `_URLFetchResult` which cause the `in` operator to throw an exception saying that it was not iterable. So, I added a type-check to prevent falling into this case and now all is well.

```
Traceback (most recent call last):
  File "/home/vmagent/app/prediction/pipelines_util.py", line 661, in __exit__
    metadata['gcs_file'].close()
  File "/home/vmagent/app/third_party/cloudstorage/storage_api.py", line 754, in close
    self._flush(finish=True)
  File "/home/vmagent/app/third_party/cloudstorage/storage_api.py", line 808, in _flush
    self._send_data(data, self._written, file_len)
  File "/home/vmagent/app/third_party/cloudstorage/storage_api.py", line 834, in _send_data
    self._path_with_token, payload=data, headers=headers)
  File "/home/vmagent/app/third_party/cloudstorage/rest_api.py", line 54, in sync_wrapper
    return future.get_result()
  File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/tasklets.py", line 325, in get_result
    self.check_success()
  File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along
    value = gen.throw(exc.__class__, exc, tb)
  File "/home/vmagent/app/third_party/cloudstorage/storage_api.py", line 129, in do_request_async
    deadline=deadline, callback=callback)
  File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along
    value = gen.throw(exc.__class__, exc, tb)
  File "/home/vmagent/app/third_party/cloudstorage/rest_api.py", line 188, in do_request_async
    follow_redirects=False)
  File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along
    value = gen.throw(exc.__class__, exc, tb)
  File "/home/vmagent/app/third_party/cloudstorage/api_utils.py", line 163, in run
    result = yield tasklet(**kwds)
  File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along
    value = gen.throw(exc.__class__, exc, tb)
  File "/home/vmagent/app/third_party/cloudstorage/rest_api.py", line 254, in urlfetch_async
    deadline=deadline, callback=callback)
  File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along
    value = gen.throw(exc.__class__, exc, tb)
  File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/context.py", line 1276, in urlfetch
    result = yield rpc
  File "/home/vmagent/python_vm_runtime/google/appengine/ext/ndb/tasklets.py", line 454, in _on_rpc_completion
    result = rpc.get_result()
  File "/home/vmagent/python_vm_runtime/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result
    return self.__get_result_hook(self)
  File "/home/vmagent/python_vm_runtime/google/appengine/api/urlfetch.py", line 376, in _get_fetch_result
    rpc.check_success()
  File "/home/vmagent/python_vm_runtime/google/appengine/api/apiproxy_stub_map.py", line 579, in check_success
    self.__rpc.CheckSuccess()
  File "/home/vmagent/python_vm_runtime/google/appengine/ext/vmruntime/vmstub.py", line 248, in _WaitImpl
    response = self._result_future.get()
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 554, in get
    raise self._value
ConnectionError: ('Connection aborted.', timeout('timed out',))
```

Test Plan:
Deploy to production with:

`python deploy/deploy.py -fxtk8v znd-faus-testvms -m vm`

Launch my pipeline job by hitting https://www.khanacademy.org/admin/prediction/features_thetas?pipeline_id=a97c65107cd411e4aeda1e7f2780d096

Then verify that it ran to completion https://www.khanacademy.org/_ah/pipeline/status?root=94b90aa6800911e49ec25ee2bf3e11b9#pipeline-94b90aa6800911e49ec25ee2bf3e11b9
Also, verify that none of these `ConnectionError`s showed up in the logs.

Auditors: tony