docs: def _execute_with_retries(conn, function, **kwargs):
      '''
      Retry if we're rate limited by AWS or blocked by another call.
      Give up and return error message if resource not found or argument is invalid.
  
      conn
          The connection established by the calling method via _get_conn()
  
      function
          The function to call on conn. i.e. create_stream
  
      **kwargs
          Any kwargs required by the above function, with their keywords
          i.e. StreamName=stream_name
  
      Returns:
          The result dict with the HTTP response and JSON data if applicable
          as 'result', or an error as 'error'
  
      CLI example::
  
          salt myminion boto_kinesis._execute_with_retries existing_conn function_name function_kwargs
  
      '''
      r = {}
      max_attempts = 18
      max_retry_delay = 10
      for attempt in range(max_attempts):
          log.info("attempt: %s function: %s", attempt, function)
          try:
              fn = getattr(conn, function)
              r['result'] = fn(**kwargs)
              return r
          except botocore.exceptions.ClientError as e:
              error_code = e.response['Error']['Code']
              if "LimitExceededException" in error_code or "ResourceInUseException" in error_code:
                  # could be rate limited by AWS or another command is blocking,
                  # retry with exponential backoff
                  log.debug("Retrying due to AWS exception", exc_info=True)
                  time.sleep(_jittered_backoff(attempt, max_retry_delay))
              else:
                  # ResourceNotFoundException or InvalidArgumentException
                  r['error'] = e.response['Error']
                  log.error(r['error'])
                  r['result'] = None
                  return r
  
      r['error'] = "Tried to execute function {0} {1} times, but was unable".format(function, max_attempts)
      log.error(r['error'])
      return r