18

I have a Google AppEngine application which runs great on my local machine. The app posts a image (from a url) to my facebook wall. However, when I deploy it to Google's servers, I get an error:

DeadlineExceededError: Deadline exceeded while waiting for HTTP response from URL: 

The offending code is:

facebook_access_token = facebook_info['access_token']

facebook_post_url = 'https://graph.facebook.com/me/photos?access_token=%s&url=%s&name=%s&method=post' % (facebook_access_token, url, caption)
facebook_post_url = facebook_post_url.replace(" ", "+");
facebook_result = urlfetch.fetch(facebook_post_url)

if facebook_result.status_code == 200:
  facebook_result_object = json.loads(facebook_result.content) 
  output_ids['facebook'] = facebook_result_object['id']
else:
  output_ids['facebook'] = ''

Ans the full error trace is:

Traceback (most recent call last):
  File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/_webapp25.py", line 710, in __call__
    handler.get(*groups)
  File "/base/data/home/apps/s~digibackapi/1.362663258877230387/main.py", line 512, in get
    facebook_result = urlfetch.fetch(facebook_post_url)
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/urlfetch.py", line 266, in fetch
    return rpc.get_result()
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 604, in get_result
    return self.__get_result_hook(self)
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/urlfetch.py", line 404, in _get_fetch_result
    'Deadline exceeded while waiting for HTTP response from URL: ' + url)
DeadlineExceededError: Deadline exceeded while waiting for HTTP response from URL: https://graph.facebook.com/me/photos?access_token=<ACCESS_TOKEN>&url=http://digiback.cc/ej7&name=Trees&method=post

Again, the code looks solid to me, and it works ok on my local machine. Could it have something t do with timeouts? When I try the facebook_post_url in a browser, it returns instantly.

Does anyone have any ideas? I am ata complete loss here.

Many thanks!

Brett
  • 11,637
  • 34
  • 127
  • 213
  • Shot in the dark, but have you tried it with other images? Since your URL looks like it is constructed properly, I'm wondering if this has something to do with the image you are including as your `url` parameter. This is completely unfounded, but I'm curious as to how the shortened URL is being resolved, and if perhaps using a direct URL would work (at least as a test). Also, you could use `urllib.urlencode` to build the URL, but we can work with that once we get this solved :) – RocketDonkey Oct 24 '12 at 15:10
  • Unfortunately subbing in a hardcoded full url didn't help :-/ I realize the DDE error is a generic urlfetch error, and from the description it appears as if the urlfetch request is taking too long. But why then is the call almost instantaneous in a browser and when run in my local appengine environment? – Brett Oct 24 '12 at 15:23
  • 2
    Have you set the site_url/domain in developers.facebook.com correctly (I assume it 127.0.0.1 for local testing)? Also adjust urlfetch deadline. https://developers.google.com/appengine/docs/python/urlfetch/fetchfunction (it defaults to 5 seconds) – Rob Curtis Oct 24 '12 at 15:41
  • @Bert Looks like increasing the Deadline did it. I guess the Facebook image post (even from a url) simply takes longer than 5 seconds. Thanks for your help! If you want to post this as a formal answer, I'll accept it. – Brett Oct 24 '12 at 16:00
  • @Brett Great! I also usually put my facebook calls in a deferred task too in case they take a long time (not sure if you're already doing that). – Rob Curtis Oct 24 '12 at 16:25

5 Answers5

29

Simple answer: the default deadline for url fetching is set to 5 seconds.

How to fix:

from google.appengine.api import urlfetch

urlfetch.set_default_fetch_deadline(60)
Randy Sugianto 'Yuku'
  • 71,383
  • 57
  • 178
  • 228
  • 1
    The 60 seconds might be important. I suspect GAE will not observe a larger value. – Eric Walker May 15 '14 at 00:43
  • 2
    @EricWalker Seems so yes: "You can set a deadline for a request, the most amount of time the service will wait for a response. By default, the deadline for a fetch is 5 seconds. The maximum deadline is 60 seconds for HTTP requests and 10 minutes for task queue and cron job requests." – Tjorriemorrie Aug 08 '14 at 15:24
9

Try setting the deadline for urlfetch to 30seconds or more(depending on whether you're calling urlfetch from within a task handler or request handler)

More info about urlfetch:Url Fetch Docs

Rob Curtis
  • 2,245
  • 24
  • 33
1

An alternative to setting the deadline globally is to set it on the specific fetch call. In your case:

result = urlfetch.fetch(
    url=your_url,
    deadline=60
)
Arjun Mehta
  • 2,500
  • 1
  • 24
  • 40
0

I am not familiar with the facebook API's. But the way the urlfetch is constructed looks a bit strange. Normaly the method (Post) is a urlfetch argument and the post payload is urlencoded. This results in:

params = urllib.urlencode([
    ('access_token', facebook_access_token),
    ('url', url),
    ('name', caption),
  ])
 response = urlfetch.fetch(url='https://graph.facebook.com/me/photos', payload=params, method=urlfetch.POST,
                      headers={'Content-Type': 'application/x-www-form-urlencoded'})
voscausa
  • 11,253
  • 2
  • 39
  • 67
0

Possibly related: I was experiencing the same deadline exceeded when testing local urlfetch code. It turns out that while a direct GET of a resource on the dev server via a browser would work, e.g., http://localhost:8080/content/test.jpg, trying the same via urlfetch was doomed to fail every time. I can only assume that fetching from localhost, which is translated to 127.0.0.1 at runtime, is not supported by urlfetch.

It turns out that yours was truly a timeout issue, whereas my answer is to not use urlfetch in dev.

Dylan
  • 1,658
  • 1
  • 19
  • 25