Can any body help me to analyse the error stack:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/tornado/web.py", line 1144, in _when_complete
if result.result() is not None:
File "/usr/local/lib/python2.7/site-packages/tornado/concurrent.py", line 129, in result
raise_exc_info(self.__exc_info)
File "/usr/local/lib/python2.7/site-packages/tornado/stack_context.py", line 302, in wrapped
ret = fn(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 550, in inner
self.set_result(key, result)
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 476, in set_result
self.run()
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 505, in run
yielded = self.gen.throw(*exc_info)
File "get_image.py", line 53, in async_fetch
yield _f
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 496, in run
next = self.yield_point.get_result()
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 395, in get_result
return self.runner.pop_result(self.key).result()
File "/usr/local/lib/python2.7/site-packages/tornado/concurrent.py", line 129, in result
raise_exc_info(self.__exc_info)
File "/usr/local/lib/python2.7/site-packages/tornado/stack_context.py", line 302, in wrapped
ret = fn(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 550, in inner
self.set_result(key, result)
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 476, in set_result
self.run()
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 505, in run
yielded = self.gen.throw(*exc_info)
File "get_image.py", line 60, in async_fetch
yield _f
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 496, in run
next = self.yield_point.get_result()
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 395, in get_result
return self.runner.pop_result(self.key).result()
File "/usr/local/lib/python2.7/site-packages/tornado/concurrent.py", line 129, in result
raise_exc_info(self.__exc_info)
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 221, in wrapper
runner.run()
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 507, in run
yielded = self.gen.send(next)
File "get_image.py", line 43, in async_fetch
request_timeout=request_timeout)
File "/usr/local/lib/python2.7/site-packages/tornado/httpclient.py", line 199, in fetch
self.fetch_impl(request, handle_response)
File "/usr/local/lib/python2.7/site-packages/tornado/curl_httpclient.py", line 95, in fetch_impl
self._process_queue()
File "/usr/local/lib/python2.7/site-packages/tornado/curl_httpclient.py", line 233, in _process_queue
curl.info["headers"])
File "/usr/local/lib/python2.7/site-packages/tornado/curl_httpclient.py", line 295, in _curl_setup_request
curl.setopt(pycurl.URL, native_str(request.url))
TypeError: unsetopt() is not supported for this option
here is the async_fetch function:
@tornado.gen.coroutine
def async_fetch(self, ourl, callback, headers=None, connect_timeout=3, request_timeout=12, replace=False):
assert callable(callback)
if ourl not in FETCHING or replace:
future = GlobalAsyncClient.fetch(ourl, headers=headers, connect_timeout=connect_timeout,
request_timeout=request_timeout)
FETCHING[ourl] = future
else:
future = FETCHING[ourl]
try:
response = yield future
except Exception as exc:
if isinstance(exc, HTTPError) and exc.response is not None:
_f = callback(exc.response)
if _f is not None:
yield _f
else:
self.log_exception(*sys.exc_info())
self.return_error(404, 10, "can't get original image")
else:
_f = callback(response)
if _f is not None:
yield _f
finally:
FETCHING.pop(ourl, None)
and one of the callback may like this:
def get_image_size(self, response, dest_file, original_file, ourl=None, whole=False):
if err_ourl(response.effective_url):
self.return_error(404, 10, "no such image")
callback = functools.partial(self.get_image_size, dest_file=dest_file, original_file=original_file, whole=True)
if response.error:
if response.error.code == 416:
return self.async_fetch(ourl, callback, replace=True)
self.return_error(404, 10, str(response.error))
try:
if getimagesize.format_fromstring(response.body) == 'WEBP':
return self.async_fetch(ourl, callback, replace=True)
# noinspection PyStringFormat
result = '{"w":%d, "h":%d}' % getimagesize.fromfileobj(response.buffer)[1:]
except IOError:
self.return_error(500, 10, "read/write image error")
except:
self.log_exception(*sys.exc_info())
self.return_error(400, 10, "can't recognise img")
else:
self.set_header("Content-Type", "application/json")
self.success_return(result)
safe_write(dest_file, result)
if whole:
safe_write(original_file, response.body)
here is the situation: I'm using curl_httpclient
in tornado, fetching image file and get the size. first using Range
header to get som bytes, if the remote server dons't support this, then try to redownload without Range
, when the image is webp formated, go download the whole file.
Holding the fetch
Future
object to reuse it when the same requests coming at the same time.
it works fine, but I got the TypeError
sometimes.
I'm using python 2.7, tornado 3.1.1, pycurl 7.19.0, libcurl.x86_64 7.19.7-40.el6_6.4
That's a bad error message from pycurl; what it means is "URL may not be None". The URL is getting lost sometimes through the chain of retries (e.g. when you construct the functools.partial(self.get_image_size)
)