Невозможно обработать DeadlineExceededError при использовании UrlFetch - PullRequest
15 голосов
/ 21 апреля 2011

У меня есть этот базовый служебный класс, который извлекает (возможно) сокращенные URL-адреса параллельно и возвращает словарь с окончательными URL-адресами. Он использует функцию wait_any, которая была описана в этом сообщении в блоге .

class UrlFetcher(object):

  @classmethod
  def fetch_urls(cls,url_list):
    rpcs = []
    for url in url_list:
      rpc = urlfetch.create_rpc(deadline=5.0)
      urlfetch.make_fetch_call(rpc, url,method = urlfetch.HEAD)
      rpcs.append(rpc)

    result = {}
    while len(rpcs) > 0:
      rpc = apiproxy_stub_map.UserRPC.wait_any(rpcs)
      rpcs.remove(rpc)
      request_url = rpc.request.url()
      try:
        final_url = rpc.get_result().final_url
      except AttributeError:
        final_url = request_url
      except DeadlineExceededError:
        logging.error('Handling DeadlineExceededError for url: %s' %request_url)
        final_url  = None
      except (DownloadError,InvalidURLError):
        final_url  = None        
      except UnicodeDecodeError: #Funky url with very evil characters
        final_url = unicode(rpc.get_result().final_url,'utf-8')

      result[request_url] = final_url

    logging.info('Returning results: %s' %result)
    return result

Даже если я попытаюсь обработать DeadlineExceededError, журналы приложения показывают иначе.

2011-04-20 17:06:17.755
UrlFetchWorker started
E 2011-04-20 17:06:22.769
The API call urlfetch.Fetch() took too long to respond and was cancelled.
Traceback (most recent call last):
  File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 636, in __call__
    handler.post(*groups)
  File "/base/data/home/apps/tweethitapp/1.349863151373877476/tweethit/handlers/taskworker.py", line 80, in post
    result_dict = UrlFetcher.fetch_urls(fetch_targets)
  File "/base/data/home/apps/tweethitapp/1.349863151373877476/tweethit/utils/rpc.py", line 98, in fetch_urls
    final_url = rpc.get_result().final_url
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 592, in get_result
    return self.__get_result_hook(self)
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/urlfetch.py", line 345, in _get_fetch_result
    rpc.check_success()
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 558, in check_success
    self.__rpc.CheckSuccess()
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_rpc.py", line 133, in CheckSuccess
    raise self.exception
DeadlineExceededError: The API call urlfetch.Fetch() took too long to respond and was cancelled.
W 2011-04-20 17:06:22.858
Found 1 RPC request(s) without matching response (presumably due to timeouts or other errors)

Что мне здесь не хватает? Есть ли другой способ обработки DeadlineExceededError?

Или существуют различные типы ошибок DeadlineExceededErrors, и я импортирую неправильный? Я использую: from google.appengine.runtime import DeadlineExceededError

Ответы [ 2 ]

20 голосов
/ 21 апреля 2011

По встроенным документам для google.appengine.runtime.DeadlineExceededError:

Исключение возникает при запросе достигает общего лимита времени.

Не путать с runtime.apiproxy_errors.DeadlineExceededError. Это поднимается, когда индивидуальный API звонки занимают слишком много времени.

Это хорошая демонстрация того, почему вы должны использовать квалифицированный импорт (from google.appengine import runtime, затем ссылка runtime.DeadlineExceededError)!

10 голосов
/ 16 октября 2012

Как вы уже догадались и другие заметили, вы хотите другое DeadlineExceededError:

С https://developers.google.com/appengine/articles/deadlineexceedederrors, от июня 2012 г .:

В настоящее время существует несколько ошибок с именем DeadlineExceededError для среды выполнения Python:>

google.appengine.runtime.DeadlineExceededError : возникает, если общий запрос истекает, обычно через 60 секунд или 10 минут для запросов очереди задач;

google.appengine.runtime.apiproxy_errors.DeadlineExceededError : повышается, если RPC превысил свой срок. Обычно это 5 секунд, но его можно установить для некоторых API, используя параметр 'deadline';

google.appengine.api.urlfetch_errors.DeadlineExceededError : повышается при превышении времени ожидания URLFetch.

Поймать google.appengine.api.urlfetch_errors.DeadlineExceededError, кажется, помогает мне. Также стоит отметить, что (по крайней мере, на сервере приложений dev 1.7.1), urlfetch_errors.DeadlineExceededError является подклассом DownloadError, что имеет смысл:

class DeadlineExceededError(DownloadError):
  """Raised when we could not fetch the URL because the deadline was exceeded.

  This can occur with either the client-supplied 'deadline' or the system
  default, if the client does not supply a 'deadline' parameter.
  """
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...