Browse Source

Raise the original error instead of a proxy in member list errors

pull/10109/head
dolfies 3 years ago
parent
commit
73f337d709
  1. 8
      discord/guild.py
  2. 44
      discord/state.py

8
discord/guild.py

@ -3576,6 +3576,8 @@ class Guild(Hashable):
ClientException
This guild cannot be chunked or chunking failed.
Guild is no longer available.
InvalidData
Did not receive a response from the gateway.
Returns
--------
@ -3588,8 +3590,6 @@ class Guild(Hashable):
raise ClientException('This guild is no longer available')
members = await self._state.chunk_guild(self, channels=[channel] if channel else [])
if members is None:
raise ClientException('Chunking failed')
return members
async def fetch_members(
@ -3633,6 +3633,8 @@ class Guild(Hashable):
ClientException
Fetching members failed.
Guild is no longer available.
InvalidData
Did not receive a response from the gateway.
Returns
--------
@ -3645,8 +3647,6 @@ class Guild(Hashable):
members = await self._state.scrape_guild(
self, cache=cache, force_scraping=force_scraping, delay=delay, channels=channels
)
if members is None:
raise ClientException('Fetching members failed')
return members
async def query_members(

44
discord/state.py

@ -48,7 +48,7 @@ import weakref
import inspect
from math import ceil
from .errors import NotFound
from .errors import ClientException, InvalidData, NotFound
from .guild import CommandCounts, Guild
from .activity import BaseActivity
from .user import User, ClientUser
@ -175,7 +175,8 @@ class MemberSidebar:
self.channels = [str(channel.id) for channel in (channels or self.get_channels(1 if chunk else 5))]
self.ranges = self.get_ranges()
self.subscribing: bool = False
self.buffer: Optional[List[Member]] = []
self.buffer: List[Member] = []
self.exception: Optional[Exception] = None
self.waiters: List[asyncio.Future[Optional[List[Member]]]] = []
def __bool__(self) -> bool:
@ -281,7 +282,7 @@ class MemberSidebar:
for member in members:
guild._add_member(member)
async def wait(self) -> Optional[List[Member]]:
async def wait(self) -> List[Member]:
future = self.loop.create_future()
self.waiters.append(future)
try:
@ -289,7 +290,7 @@ class MemberSidebar:
finally:
self.waiters.remove(future)
def get_future(self) -> asyncio.Future[Optional[List[Member]]]:
def get_future(self) -> asyncio.Future[List[Member]]:
future = self.loop.create_future()
self.waiters.append(future)
return future
@ -297,7 +298,10 @@ class MemberSidebar:
def done(self) -> None:
for future in self.waiters:
if not future.done():
future.set_result(self.buffer)
if self.exception:
future.set_exception(self.exception)
else:
future.set_result(self.buffer)
try:
del self.state._scrape_requests[self.guild.id]
@ -310,11 +314,11 @@ class MemberSidebar:
async def wrapper(self):
try:
await self.scrape()
except RuntimeError as exc:
_log.warning('Member list scraping failed for %s (%s).', self.guild.id, exc)
self.buffer = None
except asyncio.CancelledError:
pass
except Exception as exc:
_log.warning('Member list scraping failed for %s (%s).', self.guild.id, exc)
self.exception = exc
finally:
self.done()
@ -337,7 +341,7 @@ class MemberSidebar:
break
if not requests:
raise RuntimeError('failed to choose channels or ranges')
raise ClientException('Failed to automatically choose channels; please specify them manually')
def predicate(data):
return int(data['guild_id']) == guild.id and any(op['op'] == 'SYNC' for op in data['ops'])
@ -352,7 +356,7 @@ class MemberSidebar:
self.subscribing = False
break
else:
raise RuntimeError('timeout: no response from gateway')
raise InvalidData('Did not receive a response from Discord')
await asyncio.sleep(delay)
@ -790,6 +794,8 @@ class ConnectionState:
await asyncio.wait_for(future, timeout=10)
except asyncio.TimeoutError:
_log.warning('Timed out waiting for chunks for guild_id %s.', guild.id)
except (ClientException, InvalidData):
pass
except asyncio.CancelledError:
pass
else:
@ -891,7 +897,7 @@ class ConnectionState:
self.session_type = data.get('session_type', 'normal')
self.connections = {c['id']: Connection(state=self, data=c) for c in data.get('connected_accounts', [])}
if 'required_action' in data: # Locked more than likely
if 'required_action' in data:
self.parse_user_required_action_update(data)
if 'sessions' in data:
@ -1720,7 +1726,7 @@ class ConnectionState:
force_scraping: bool = ...,
channels: List[abcSnowflake] = ...,
delay: Union[int, float] = ...,
) -> Optional[List[Member]]:
) -> List[Member]:
...
@overload
@ -1733,7 +1739,7 @@ class ConnectionState:
force_scraping: bool = ...,
channels: List[abcSnowflake] = ...,
delay: Union[int, float] = ...,
) -> asyncio.Future[Optional[List[Member]]]:
) -> asyncio.Future[List[Member]]:
...
async def scrape_guild(
@ -1745,7 +1751,7 @@ class ConnectionState:
force_scraping: bool = False,
channels: List[abcSnowflake] = MISSING,
delay: Union[int, float] = MISSING,
) -> Union[Optional[List[Member]], asyncio.Future[Optional[List[Member]]]]:
) -> Union[List[Member], asyncio.Future[List[Member]]]:
if not guild.me:
await guild.query_members(user_ids=[self.self_id], cache=True) # type: ignore # self_id is always present here
@ -1773,18 +1779,18 @@ class ConnectionState:
if wait:
return await request.wait()
return request.get_future() # type: ignore # Honestly, I'm confused too
return request.get_future()
@overload
async def chunk_guild(
self, guild: Guild, *, wait: Literal[True] = ..., channels: List[abcSnowflake] = ...
) -> Optional[List[Member]]:
) -> List[Member]:
...
@overload
async def chunk_guild(
self, guild: Guild, *, wait: Literal[False] = ..., channels: List[abcSnowflake] = ...
) -> asyncio.Future[Optional[List[Member]]]:
) -> asyncio.Future[List[Member]]:
...
async def chunk_guild(
@ -1793,7 +1799,7 @@ class ConnectionState:
*,
wait: bool = True,
channels: List[abcSnowflake] = MISSING,
) -> Union[asyncio.Future[Optional[List[Member]]], Optional[List[Member]]]:
) -> Union[asyncio.Future[List[Member]], List[Member]]:
if not guild.me:
await guild.query_members(user_ids=[self.self_id], cache=True) # type: ignore # self_id is always present here
@ -1816,6 +1822,8 @@ class ConnectionState:
await asyncio.wait_for(self.chunk_guild(guild), timeout=10)
except asyncio.TimeoutError:
_log.info('Somehow timed out waiting for chunks for guild %s.', guild.id)
except (ClientException, InvalidData):
pass
self._queued_guilds.pop(guild.id)

Loading…
Cancel
Save