dolfies / discord.py-self

A fork of the popular discord.py for user accounts.
https://discordpy-self.rtfd.io/en/latest/
MIT License
648 stars 153 forks source link

KeyError: 'browser_user_agent' #692

Closed TheKidThatCodes closed 1 month ago

TheKidThatCodes commented 1 month ago

Summary

maybe its because im doing cursed stuff but its erroring

Reproduction Steps

idk, i reimplemented bot.connect so i can have multiple at once and add and remove on the fly, i need a better way to do that

Code

# this is in a custom bot subclass

    async def pool_connect_setup(self):
        self.pool_backoff = ExponentialBackoff()
        self.pool_ws_params = {
            'initial': True,
        }

    async def stable_loop(self):
        try:
            await self.signle_iter()
        except Exception as e:
            if not await self.pool_connect_handle_error(e):
                await self.stable_loop()
            else:
                raise e
    async def safe_single_iter(self):
        try:
            await self.signle_iter()
        except Exception as e:
            await self.pool_connect_handle_error(e)
    async def signle_iter(self):
        await self.pool_connect_iter_setup()
        await self.pool_connect_iter(self.reconnect)
    async def pool_connect_iter_setup(self, reconnect: bool = True):
        coro = DiscordWebSocket.from_client(self, **self.pool_ws_params)
        self.ws = await aio.wait_for(coro, timeout=60.0)
        self.pool_ws_params['initial'] = False
        self.reconnect = reconnect

    async def pool_connect_iter(self, reconnect: bool = True):
        await self.ws.poll_event()

    async def pool_connect_handle_error(self, e:Exception):
        print()
        print_exception(e)
        print()
        if isinstance(e, ReconnectWebSocket):
            # _log.debug('Got a request to %s the websocket.', e.op)
            self.dispatch('disconnect')
            self.pool_ws_params.update(sequence=self.ws.sequence, resume=e.resume, session=self.ws.session_id)
            if e.resume:
                self.pool_ws_params['gateway'] = self.ws.gateway
            return 0
        if isinstance(
            e,
            OSError | HTTPException | GatewayNotFound | ConnectionClosed | aiohttp.ClientError | aio.TimeoutError
        ):
            self.dispatch('disconnect')
            if not self.reconnect:
                await self.close()
                if isinstance(e, ConnectionClosed) and e.code == 1000:
                    # Clean close, don't re-raise this
                    return 1
                raise

            if self.is_closed():
                return 1

            # If we get connection reset by peer then try to RESUME
            if isinstance(e, OSError) and e.errno in (54, 10054):
                self.pool_ws_params.update(
                    sequence=self.ws.sequence,
                    gateway=self.ws.gateway,
                    initial=False,
                    resume=True,
                    session=self.ws.session_id,
                )
                return 0

            # We should only get this when an unhandled close code happens,
            # such as a clean disconnect (1000) or a bad state (bad token, etc)
            # Sometimes, Discord sends us 1000 for unknown reasons so we should
            # reconnect regardless and rely on is_closed instead
            if isinstance(e, ConnectionClosed):
                if e.code != 1000:
                    await self.close()
                    print_exception(e)
                    return 1

            retry = self.pool_backoff.delay()
            # _log.exception("Attempting a reconnect in %.2fs", retry)
            await aio.sleep(retry)
            # Always try to RESUME the connection
            # If the connection is not RESUME-able then the gateway will invalidate the session
            # This is apparently what the official Discord client does
            self.pool_ws_params.update(
                sequence=self.ws.sequence,
                gateway=self.ws.gateway,
                resume=True,
                session=self.ws.session_id,
            )
            return 0

    async def preloaded_start(self, reconnect=True):
        await aio.create_task(self.start(self.token, reconnect=reconnect))

Expected Results

it breaks in a way that is my fault so i stop and do it a better way

Actual Results

Traceback (most recent call last): File "/NameChecker/core/base.py", line 105, in safe_single_iter await self.signle_iter() File "/NameChecker/core/base.py", line 109, in signle_iter await self.pool_connect_iter_setup() File "/NameChecker/core/base.py", line 113, in pool_connect_iter_setup self.ws = await aio.wait_for(coro, timeout=60.0) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/tasks.py", line 510, in wait_for return await fut ^^^^^^^^^ File "/.venv/lib/python3.12/site-packages/selfcord/gateway.py", line 352, in from_client socket = await client.http.ws_connect(str(url)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/.venv/lib/python3.12/site-packages/selfcord/http.py", line 657, in ws_connect 'User-Agent': self.user_agent, ^^^^^^^^^^^^^^^ File "/.venv/lib/python3.12/site-packages/selfcord/http.py", line 670, in user_agent return self.super_properties['browser_user_agent']


KeyError: 'browser_user_agent'

### System Information

- Python v3.12.0-final
- selfcord.py v2.1.0-alpha
    - selfcord.py metadata: v2.1.0a4406+g6e12bbbb
- aiohttp v3.9.0b0
- system info: Darwin 23.4.0 Darwin Kernel Version 23.4.0: Fri Mar 15 00:12:41 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T8103

### Checklist

- [X] I have searched the open issues for duplicates.
- [X] I have shared the entire traceback.
- [X] I am using a user token (and it isn't visible in the code).

### Additional Information

_No response_
dolfies commented 1 month ago

if it's not reproducible without the patching, then it's not a library issue.