interactions-py / interactions.py

A highly extensible, easy to use, and feature complete bot framework for Discord
https://interactions-py.github.io/interactions.py/
MIT License
840 stars 185 forks source link

[BUG] Invalid form body error on Role.modify_position() #741

Closed dacid44 closed 2 years ago

dacid44 commented 2 years ago

Describe the bug.

When using the Role.modify_position() function, I get a interactions.api.error.HTTPException: Invalid Form Body Error code: 50035 back.

List the steps.

  1. Set up a bot.
  2. (In a command,) try to modify the position of a role in a guild.
  3. See the traceback with the 50035 error and later a NoneType error.

What you expected.

The role's position in the guild should be changed, and I should not see any errors.

What you saw.

Instead, I received this traceback error given from my Python terminal:

ERROR:http:Traceback (most recent call last):
  File "/home/dacid44/Documents/python/cs_discord/venv/lib/python3.10/site-packages/interactions/api/http/request.py", line 169, in request
    raise HTTPException(data["code"], message=data["message"])
interactions.api.error.HTTPException: Invalid Form Body Error code: 50035

ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='Task-11' coro=<Classes.class_command() done, defined at /home/dacid44/Documents/python/cs_discord/classes.py:157> exception=TypeError("'NoneType' object is not iterable")>
Traceback (most recent call last):
  File "/home/dacid44/Documents/python/cs_discord/classes.py", line 237, in class_command
    await r.modify_position(
  File "/home/dacid44/Documents/python/cs_discord/venv/lib/python3.10/site-packages/interactions/api/models/role.py", line 170, in modify_position
    return [Role(**role, _client=self._client) for role in res]
TypeError: 'NoneType' object is not iterable

and this with debug logging enabled:

DEBUG:http:RETURN 400: {
    "code": 50035,
    "errors": {
        "_errors": [
            {
                "code": "LIST_TYPE_CONVERT",
                "message": "Only iterables may be used in a ListType"
            }
        ]
    },
    "message": "Invalid Form Body"
}

What version of the library did you use?

unstable

Version specification

4.1.1-rc.1

Code of Conduct

dacid44 commented 2 years ago

Discord's API spec (https://discord.com/developers/docs/resources/guild#modify-guild-role-positions) says that the JSON should be an array of objects (objects which look like what api.http.guild._GuildRequest.modify_guild_role_position() gives it right now. All that probably needs to be changed is wrapping the JSON object in a list, but a core dev (@Astrea49 )in the Discord mentioned using that to make it possible to change multiple roles' positions at once. I can probably make a PR if that's what's wanted, it looks like an easy fix.

the current api.http.guild._GuildRequest.modify_guild_role_position() function:

async def modify_guild_role_position(
    self, guild_id: int, role_id: int, position: int, reason: Optional[str] = None
) -> List[dict]:
    """
    Modify the position of a role in the guild.

    :param guild_id: Guild ID snowflake.
    :param role_id: Role ID snowflake.
    :param position: The new position of the associated role.
    :param reason: The reason for this action, if given.
    :return: List of guild roles with updated hierarchy.
    """
    return await self._req.request(
        Route("PATCH", f"/guilds/{guild_id}/roles"),
        json={"id": role_id, "position": position},
        reason=reason,
    )