Repository: interactions-py/interactions.py

Issue:
[BUG] Error when syncing to guild without app.cmds scope with disable_sync
### Describe the bug.

*Everything I describe is based off other people's reports and theoretical guesswork. This may be inaccurate.*

Many big bots are in a large number of guilds, and so it makes sense for them to turn off `disable_sync`. Besides for the obvious, this has another behavior, however.

Instead of erroring out if a guild has the bot without the `application.commands` scope (which is possible under certain contexts, and happens especially often for bigger bots), having `disable_sync` will instead simply warn the user - we don't need to sync to the bot so not having application commands isn't *needed*, but it is a thing to note.

However, in 4.3.1 *at least*, the bot has been erroring out when seeing a guild without the scope instead of simply warning.

### List the steps.

1. Have a bot be in a server (at least one) where it doesn't have the `application.commands` scope.
2. Start a bot with `disable_sync=True`.

### What you expected.

For interactions.py to warn the user, but not necessarily stop them.

### What you saw.

```python
interactions.api.error.LibraryException: An error occurred:
Missing Access, with code '50001' and severity '40'
Could not prepare the client:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/interactions/ext/autosharder/dummy.py", line 47, in _ready
    await self._Client__get_all_commands()
  File "/usr/local/lib/python3.8/dist-packages/interactions/client/bot.py", line 426, in __get_all_commands
    _cmds = await self._http.get_application_commands(
  File "/usr/local/lib/python3.8/dist-packages/interactions/api/http/interaction.py", line 45, in get_application_commands
    return await self._req.request(
  File "/usr/local/lib/python3.8/dist-packages/interactions/api/http/request.py", line 174, in request
    raise LibraryException(
interactions.api.error.LibraryException: An error occurred:
```

### What version of the library did you use?

stable

### Version specification

4.3.1

### Code of Conduct

- [X] I agree to follow the contribution requirements.
[BUG] Error when syncing to guild without app.cmds scope with disable_sync
### Describe the bug.

*Everything I describe is based off other people's reports and theoretical guesswork. This may be inaccurate.*

Many big bots are in a large number of guilds, and so it makes sense for them to turn off `disable_sync`. Besides for the obvious, this has another behavior, however.

Instead of erroring out if a guild has the bot without the `application.commands` scope (which is possible under certain contexts, and happens especially often for bigger bots), having `disable_sync` will instead simply warn the user - we don't need to sync to the bot so not having application commands isn't *needed*, but it is a thing to note.

However, in 4.3.1 *at least*, the bot has been erroring out when seeing a guild without the scope instead of simply warning.

### List the steps.

1. Have a bot be in a server (at least one) where it doesn't have the `application.commands` scope.
2. Start a bot with `disable_sync=True`.

### What you expected.

For interactions.py to warn the user, but not necessarily stop them.

### What you saw.

```python
interactions.api.error.LibraryException: An error occurred:
Missing Access, with code '50001' and severity '40'
Could not prepare the client:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/interactions/ext/autosharder/dummy.py", line 47, in _ready
    await self._Client__get_all_commands()
  File "/usr/local/lib/python3.8/dist-packages/interactions/client/bot.py", line 426, in __get_all_commands
    _cmds = await self._http.get_application_commands(
  File "/usr/local/lib/python3.8/dist-packages/interactions/api/http/interaction.py", line 45, in get_application_commands
    return await self._req.request(
  File "/usr/local/lib/python3.8/dist-packages/interactions/api/http/request.py", line 174, in request
    raise LibraryException(
interactions.api.error.LibraryException: An error occurred:
```

### What version of the library did you use?

stable

### Version specification

4.3.1

### Code of Conduct

- [X] I agree to follow the contribution requirements.


Discussion:
As for what causes it, my theory is that we now detect and throw an error in our HTTP requests when we previously didn't.

Take a look at [these lines that get invoked with `disable_sync=True`.](https://github.com/interactions-py/library/blob/7819ffc0d525033d9a03cd6f177b6b5f2639b0e4/interactions/client/bot.py#L426-L439). You can clearly see that triggering the warning depends on the response being a dict with a field for the "code", which represents the response returning an error.

However, as of lately, the HTTP handler has been throwing proper errors instead of returning the dict with said errors, as a part of improving the error UX of interactions.py. This is good, but it means this legacy code here doesn't account for that.

This likely can be solved by changing that whole section of code to try-except the `LibraryException` and propagating the warning from there while still suppressing the actual error.
Fun fact: #868 does the fix needed, but for syncing, not for here.
As for what causes it, my theory is that we now detect and throw an error in our HTTP requests when we previously didn't.

Take a look at [these lines that get invoked with `disable_sync=True`.](https://github.com/interactions-py/library/blob/7819ffc0d525033d9a03cd6f177b6b5f2639b0e4/interactions/client/bot.py#L426-L439). You can clearly see that triggering the warning depends on the response being a dict with a field for the "code", which represents the response returning an error.

However, as of lately, the HTTP handler has been throwing proper errors instead of returning the dict with said errors, as a part of improving the error UX of interactions.py. This is good, but it means this legacy code here doesn't account for that.

This likely can be solved by changing that whole section of code to try-except the `LibraryException` and propagating the warning from there while still suppressing the actual error.
Fun fact: #868 does the fix needed, but for syncing, not for here.

Resolving patch:
diff --git a/interactions/client/bot.py b/interactions/client/bot.py
--- a/interactions/client/bot.py
+++ b/interactions/client/bot.py
@@ -460,13 +460,13 @@ async def __get_all_commands(self) -> None:
         # responsible for checking if a command is in the cache but not a coro -> allowing removal
 
         for _id in _guild_ids:
-            _cmds = await self._http.get_application_commands(
-                application_id=self.me.id, guild_id=_id, with_localizations=True
-            )
-
-            if isinstance(_cmds, dict) and _cmds.get("code"):
-                if int(_cmds.get("code")) != 50001:
-                    raise LibraryException(_cmds["code"], message=f'{_cmds["message"]} |')
+            try:
+                _cmds = await self._http.get_application_commands(
+                    application_id=self.me.id, guild_id=_id, with_localizations=True
+                )
+            except LibraryException as e:
+                if int(e.code) != 50001:
+                    raise LibraryException(code=e.code, message=e.message)
 
                 log.warning(
                     f"Your bot is missing access to guild with corresponding id {_id}! "


Test patch: