Refactor ModrinthTracker API request handling to improve session management and retry logic. Enhance error handling for network issues and provide clearer user feedback in the add command. Add cog load and unload documentation.
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run
This commit is contained in:
parent
e72a8b9a5c
commit
fd2ace3025
1 changed files with 32 additions and 27 deletions
|
@ -24,14 +24,17 @@ class ModrinthTracker(commands.Cog):
|
||||||
self.request_lock = asyncio.Lock()
|
self.request_lock = asyncio.Lock()
|
||||||
|
|
||||||
async def cog_load(self):
|
async def cog_load(self):
|
||||||
|
"""Initialize the cog."""
|
||||||
self.session = aiohttp.ClientSession()
|
self.session = aiohttp.ClientSession()
|
||||||
self.bg_task = self.bot.loop.create_task(self.update_checker())
|
self.bg_task = self.bot.loop.create_task(self.update_checker())
|
||||||
|
|
||||||
async def cog_unload(self):
|
async def cog_unload(self):
|
||||||
if self.session:
|
"""Clean up when cog shuts down."""
|
||||||
await self.session.close()
|
|
||||||
if self.bg_task:
|
if self.bg_task:
|
||||||
self.bg_task.cancel()
|
self.bg_task.cancel()
|
||||||
|
if self.session:
|
||||||
|
await self.session.close()
|
||||||
|
self.session = None
|
||||||
|
|
||||||
async def _rate_limit(self):
|
async def _rate_limit(self):
|
||||||
"""Implements rate limiting for API requests"""
|
"""Implements rate limiting for API requests"""
|
||||||
|
@ -54,32 +57,34 @@ class ModrinthTracker(commands.Cog):
|
||||||
|
|
||||||
self.request_timestamps.append(current_time)
|
self.request_timestamps.append(current_time)
|
||||||
|
|
||||||
async def _make_request(self, url, params=None):
|
async def _make_request(self, url, params=None, retries=3):
|
||||||
"""Make a rate-limited request to the Modrinth API"""
|
"""Make a rate-limited request to the Modrinth API"""
|
||||||
await self._rate_limit()
|
await self._rate_limit()
|
||||||
|
|
||||||
# Ensure session is available
|
for attempt in range(retries):
|
||||||
if self.session is None or self.session.closed:
|
try:
|
||||||
self.session = aiohttp.ClientSession()
|
# Ensure session is available
|
||||||
|
if self.session is None or self.session.closed:
|
||||||
try:
|
self.session = aiohttp.ClientSession()
|
||||||
async with self.session.get(url, params=params) as response:
|
|
||||||
if response.status == 429: # Too Many Requests
|
async with self.session.get(url, params=params) as response:
|
||||||
retry_after = int(response.headers.get('Retry-After', 60))
|
if response.status == 429: # Too Many Requests
|
||||||
await asyncio.sleep(retry_after)
|
retry_after = int(response.headers.get('Retry-After', 60))
|
||||||
return await self._make_request(url, params)
|
await asyncio.sleep(retry_after)
|
||||||
return response
|
continue
|
||||||
except aiohttp.ClientConnectorError:
|
return response
|
||||||
# Connection error, try to recreate session and retry once
|
|
||||||
if self.session and not self.session.closed:
|
except (aiohttp.ClientConnectorError, aiohttp.ClientError) as e:
|
||||||
await self.session.close()
|
if attempt == retries - 1: # Last attempt
|
||||||
self.session = aiohttp.ClientSession()
|
raise
|
||||||
async with self.session.get(url, params=params) as response:
|
# Close and recreate session
|
||||||
return response
|
if self.session and not self.session.closed:
|
||||||
except Exception as e:
|
await self.session.close()
|
||||||
# Log the error for debugging
|
self.session = aiohttp.ClientSession()
|
||||||
self.bot.logger.error(f"Error in _make_request: {str(e)}", exc_info=True)
|
await asyncio.sleep(1) # Wait a bit before retrying
|
||||||
raise
|
except Exception as e:
|
||||||
|
self.bot.logger.error(f"Error in _make_request: {str(e)}", exc_info=True)
|
||||||
|
raise
|
||||||
|
|
||||||
@commands.group()
|
@commands.group()
|
||||||
@checks.admin()
|
@checks.admin()
|
||||||
|
@ -170,12 +175,12 @@ class ModrinthTracker(commands.Cog):
|
||||||
except aiohttp.ClientConnectorError:
|
except aiohttp.ClientConnectorError:
|
||||||
await ctx.send("Error: Failed to connect to Modrinth API. Please try again in a few moments.")
|
await ctx.send("Error: Failed to connect to Modrinth API. Please try again in a few moments.")
|
||||||
except aiohttp.ClientError as e:
|
except aiohttp.ClientError as e:
|
||||||
await ctx.send(f"Error: Network error occurred while contacting Modrinth API: {str(e)}")
|
await ctx.send(f"Error: Network error occurred while contacting Modrinth API. Please try again in a few moments.")
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
await ctx.send("Error: Request to Modrinth API timed out. Please try again.")
|
await ctx.send("Error: Request to Modrinth API timed out. Please try again.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.bot.logger.error(f"Error in modrinth add command: {str(e)}", exc_info=True)
|
self.bot.logger.error(f"Error in modrinth add command: {str(e)}", exc_info=True)
|
||||||
await ctx.send(f"An unexpected error occurred. Please try again later or contact the bot owner if the issue persists.")
|
await ctx.send("An unexpected error occurred. Please try again later or contact the bot owner if the issue persists.")
|
||||||
|
|
||||||
@modrinth.command()
|
@modrinth.command()
|
||||||
async def remove(self, ctx, project_id: str):
|
async def remove(self, ctx, project_id: str):
|
||||||
|
|
Loading…
Add table
Reference in a new issue