No se puede manejar DeadlineExceededError mientras se usa UrlFetch

Tengo esta clase de utilidad básica que recupera (posiblemente) las URL acortadas en paralelo y devuelve un diccionario que tiene las URL finales. Utiliza la funcionalidad wait_any que se describió en esta publicación del blog .

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 

Incluso si trato de manejar DeadlineExceededError, los registros de la aplicación muestran lo contrario.

 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 (presumbly due to timeouts or other errors) 

¿Que me estoy perdiendo aqui? ¿Hay alguna otra manera de manejar DeadlineExceededError?

¿O hay diferentes tipos de DeadlineExceededErrors y estoy importando el incorrecto? Estoy usando: from google.appengine.runtime import DeadlineExceededError

Por los documentos en línea para google.appengine.runtime.DeadlineExceededError :

Excepción generada cuando la solicitud alcanza su límite de tiempo total.

No debe confundirse con runtime.apiproxy_errors.DeadlineExceededError. Ese se genera cuando las llamadas API individuales toman demasiado tiempo.

Esta es una buena demostración de por qué debería usar importaciones calificadas ( from google.appengine import runtime , luego runtime.DeadlineExceededError referencia a runtime.DeadlineExceededError ), también.

Como lo adivinó y otros lo señalaron, desea un DeadlineExceededError diferente:

De https://developers.google.com/appengine/articles/deadlineexceedederrors , con fecha de junio de 2012:

Actualmente, hay varios errores llamados DeadlineExceededError para el tiempo de ejecución de Python:>

google.appengine.runtime.DeadlineExceededError : se genera si la solicitud general se agota, generalmente después de 60 segundos, o 10 minutos para las solicitudes de cola de tareas;

google.appengine.runtime.apiproxy_errors.DeadlineExceededError : se genera si un RPC supera su fecha límite. Esto suele ser de 5 segundos, pero se puede configurar para algunas API utilizando la opción ‘fecha límite’;

google.appengine.api.urlfetch_errors.DeadlineExceededError : se genera si el URLFetch se agota.

Coger google.appengine.api.urlfetch_errors.DeadlineExceededError parece hacer el truco por mí. También vale la pena señalar que (al menos en el servidor de aplicaciones dev 1.7.1), urlfetch_errors.DeadlineExceededError es una subclase de DownloadError , lo que tiene sentido:

 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. """