recurly-client-python icon indicating copy to clipboard operation
recurly-client-python copied to clipboard

CannotSendRequest thrown from httplib and unhandled by Recurly

Open dgilmanAIDENTIFIED opened this issue 3 years ago • 2 comments

Describe the bug

When the Recurly service is down the Python library can throw a CannotSendRequest from httplib. The exception is unhandled in recurly so that's probably a problem by itself. But googling the error also says that it has to do with the usage of the httplib library and a connection is being re-used when it should be recycled.

This code wraps recurly python API function calls in an exception handler which intercepts recurly.errors.ServerError and recurly.NetworkError and retries a few times before giving up.

CannotSendRequest: Request-sent
  File "django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "rest_framework/viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "django/utils/decorators.py", line 46, in _wrapper
    return bound_method(*args, **kwargs)
  File "django/views/decorators/cache.py", line 40, in _cache_controlled
    response = viewfunc(request, *args, **kw)
  File "coredata_api/tools/http.py", line 14, in _inner
    return fn(*args, **kwargs)
  File "coredata_api/api_v0/views/recurly.py", line 470, in list
    subscriptions = recurly_retry_or_halt(
  File "coredata_api/tools/recurly.py", line 60, in recurly_retry_or_halt
    batch = recurly_retry(functools.partial(next, pager))
  File "coredata_api/tools/recurly.py", line 32, in recurly_retry
    return callable()
  File "recurly/pager.py", line 40, in __next__
    page = self.__client._make_request(
  File "recurly/base_client.py", line 69, in _make_request
    self.__conn.request(method, path, body, headers=headers)
  File "http/client.py", line 1253, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "http/client.py", line 1264, in _send_request
    self.putrequest(method, url, **skips)
  File "http/client.py", line 1090, in putrequest
    raise CannotSendRequest(self.__state)

To Reproduce

Recurly API instability on 4/19 triggered this

Your Environment

recurly 4.14.0 python 3.9.5

dgilmanAIDENTIFIED avatar Apr 19 '22 13:04 dgilmanAIDENTIFIED

I am also getting this on my side - with no downtime on recurly's side, intermittently. This is the wrong implementation of the http client, it can only be used once per transaction. This means that I cannot trust the recurly client. Please fix this as it means I cannot ensure that financial transactions process correctly.

How has there been no response to this issue since April?

davidemerritt avatar Nov 09 '23 17:11 davidemerritt