Skip to content

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

@debanshuk

Description

@debanshuk

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions