pyapns icon indicating copy to clipboard operation
pyapns copied to clipboard

"RuntimeErro: maximum recursion depth exceeded" is raised when "UnknownAppID" error occurs

Open debanshuk opened this issue 10 years ago • 0 comments

Our code was calling the client.notify function with an app_id that wasn't used to exist in the settings. And we were getting "RuntimeErro: maximum recursion depth exceeded" in our error logger.

Actually, the reprovision_and_retry decorator retries the call infinitely if an UnknownAppID error occurs. And as we are making synchronous calls, it was reaching the maximum recursion depth.

def reprovision_and_retry(func):
  """
  Wraps the `errback` callback of the API functions, automatically trying to
  re-provision if the app ID can not be found during the operation. If that's
  unsuccessful, it will raise the UnknownAppID error.
  """
  @functools.wraps(func)
  def wrapper(*a, **kw):
    errback = kw.get('errback', None)
    if errback is None:
      def errback(e):
        raise e
    def errback_wrapper(e):
      if isinstance(e, UnknownAppID) and 'INITIAL' in OPTIONS:
        try:
          for initial in OPTIONS['INITIAL']:
            provision(*initial) # retry provisioning the initial setup
          func(*a, **kw) # and try the function once more          ------*1
        except Exception, new_exc:
          errback(new_exc) # throwing the new exception
      else:
        errback(e) # not an instance of UnknownAppID - nothing we can do here
    kw['errback'] = errback_wrapper           -------*2
    return func(*a, **kw)
  return wrapper

Here at *1, the keyword argument dict kw would have errback_wrapper function in 'errback' key (as stated at *2). And hence, if errback is called from func (which is done when UnknownAppID error occurs) the code will go into infinite recursion.

debanshuk avatar May 13 '14 23:05 debanshuk