fix: Enhance error handling and logging in LevelingCog UI components to ensure valid construction and prevent None returns
This commit is contained in:
parent
d6876f0e8a
commit
fa5f39b1d3
@ -404,10 +404,9 @@ class LevelingCog(commands.Cog):
|
||||
print("DEBUG: target_member is None in LevelCheckView.__init__")
|
||||
|
||||
# Main container for all elements, providing the accent color
|
||||
main_container = ui.Container(accent_colour=None)
|
||||
if not main_container:
|
||||
print("DEBUG: ui.Container returned None in LevelCheckView")
|
||||
return
|
||||
main_container = ui.Container(accent_colour=discord.Colour.blue())
|
||||
if main_container is None:
|
||||
raise AssertionError("ui.Container returned None in LevelCheckView; ensure accent_colour is valid")
|
||||
self.add_item(main_container) # Add the main container to the view
|
||||
|
||||
# Prepare thumbnail accessory
|
||||
@ -418,24 +417,31 @@ class LevelingCog(commands.Cog):
|
||||
# Section to hold the user's name and level/XP, with the thumbnail as accessory
|
||||
# This section will be added to the main_container
|
||||
user_info_section = ui.Section(accessory=thumbnail_accessory)
|
||||
if user_info_section is None:
|
||||
raise AssertionError("ui.Section returned None in LevelCheckView")
|
||||
main_container.add_item(user_info_section)
|
||||
|
||||
# Add text components to the user_info_section
|
||||
user_info_section.add_item(ui.TextDisplay(f"**{target_member.display_name}'s Level**"))
|
||||
user_info_section.add_item(ui.TextDisplay(f"**Level:** {level}\n**XP:** {xp} / {xp_needed}"))
|
||||
name_display = ui.TextDisplay(f"**{target_member.display_name}'s Level**")
|
||||
if name_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for name in LevelCheckView")
|
||||
user_info_section.add_item(name_display)
|
||||
|
||||
level_display = ui.TextDisplay(f"**Level:** {level}\n**XP:** {xp} / {xp_needed}")
|
||||
if level_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for level info in LevelCheckView")
|
||||
user_info_section.add_item(level_display)
|
||||
|
||||
# Add remaining components directly to the main_container
|
||||
separator = ui.Separator(spacing=discord.SeparatorSpacing.small)
|
||||
if separator:
|
||||
main_container.add_item(separator)
|
||||
else:
|
||||
print("DEBUG: ui.Separator returned None in LevelCheckView")
|
||||
if separator is None:
|
||||
raise AssertionError("ui.Separator returned None in LevelCheckView")
|
||||
main_container.add_item(separator)
|
||||
|
||||
progress_text = ui.TextDisplay(f"**Progress to Level {next_level}:**\n[{bar}] {progress_percent}%")
|
||||
if progress_text:
|
||||
main_container.add_item(progress_text)
|
||||
else:
|
||||
print("DEBUG: ui.TextDisplay returned None in LevelCheckView")
|
||||
if progress_text is None:
|
||||
raise AssertionError("ui.TextDisplay returned None in LevelCheckView")
|
||||
main_container.add_item(progress_text)
|
||||
|
||||
view = LevelCheckView(target, level, xp, xp_needed, next_level, bar, int(progress * 100))
|
||||
await ctx.send(view=view)
|
||||
@ -464,16 +470,26 @@ class LevelingCog(commands.Cog):
|
||||
super().__init__()
|
||||
|
||||
# Main container for all elements, providing the accent color
|
||||
main_container = ui.Container(accent_colour=discord.Color.gold())
|
||||
main_container = ui.Container(accent_colour=discord.Colour.gold())
|
||||
if main_container is None:
|
||||
raise AssertionError("ui.Container returned None in LeaderboardView; ensure accent_colour is valid")
|
||||
self.add_item(main_container) # Add the main container to the view
|
||||
|
||||
main_container.add_item(ui.TextDisplay(f"**{guild_name} Level Leaderboard**"))
|
||||
title_display = ui.TextDisplay(f"**{guild_name} Level Leaderboard**")
|
||||
if title_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for title in LeaderboardView")
|
||||
main_container.add_item(title_display)
|
||||
|
||||
sep = ui.Separator(spacing=discord.SeparatorSpacing.small)
|
||||
if sep:
|
||||
main_container.add_item(sep)
|
||||
if sep is None:
|
||||
raise AssertionError("ui.Separator returned None in LeaderboardView")
|
||||
main_container.add_item(sep)
|
||||
|
||||
if not sorted_leaderboard_data:
|
||||
main_container.add_item(ui.TextDisplay("The leaderboard is empty!"))
|
||||
empty_display = ui.TextDisplay("The leaderboard is empty!")
|
||||
if empty_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for empty message in LeaderboardView")
|
||||
main_container.add_item(empty_display)
|
||||
else:
|
||||
for i, (user_id, data) in enumerate(sorted_leaderboard_data[:10], 1):
|
||||
member = guild_members_dict.get(user_id)
|
||||
@ -482,19 +498,35 @@ class LevelingCog(commands.Cog):
|
||||
|
||||
# Each user's entry gets its own section and is added to the main_container
|
||||
user_section = ui.Section(accessory=None)
|
||||
if user_section is None:
|
||||
raise AssertionError("ui.Section returned None in LeaderboardView")
|
||||
main_container.add_item(user_section)
|
||||
|
||||
# Add text components to the user_section
|
||||
user_section.add_item(ui.TextDisplay(f"**{i}. {member.display_name}**"))
|
||||
user_section.add_item(ui.TextDisplay(f"Level: {data['level']} | XP: {data['xp']}"))
|
||||
rank_display = ui.TextDisplay(f"**{i}. {member.display_name}**")
|
||||
if rank_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for rank in LeaderboardView")
|
||||
user_section.add_item(rank_display)
|
||||
|
||||
level_display = ui.TextDisplay(f"Level: {data['level']} | XP: {data['xp']}")
|
||||
if level_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for level in LeaderboardView")
|
||||
user_section.add_item(level_display)
|
||||
|
||||
# Add separator to the main_container
|
||||
if i < len(sorted_leaderboard_data[:10]): # not the last row
|
||||
separator = ui.Separator(spacing=discord.SeparatorSpacing.small)
|
||||
if separator:
|
||||
main_container.add_item(separator)
|
||||
if separator is None:
|
||||
raise AssertionError("ui.Separator returned None between rows in LeaderboardView")
|
||||
main_container.add_item(separator)
|
||||
|
||||
view = LeaderboardView(ctx.guild.name, sorted_data, guild_members)
|
||||
|
||||
# Double-check the view is dispatchable and properly constructed
|
||||
if view is None:
|
||||
return await ctx.send("❌ Failed to build leaderboard layout. Please try again.")
|
||||
|
||||
# Send the view
|
||||
await ctx.send(view=view)
|
||||
|
||||
@level.command(name="register_role", description="Register a role for a specific level")
|
||||
@ -552,39 +584,62 @@ class LevelingCog(commands.Cog):
|
||||
def __init__(self, guild: discord.Guild, level_roles_data: dict):
|
||||
super().__init__()
|
||||
|
||||
main_container = ui.Container(accent_colour=discord.Color.blue())
|
||||
main_container = ui.Container(accent_colour=discord.Colour.blue())
|
||||
if main_container is None:
|
||||
raise AssertionError("ui.Container returned None in ListLevelRolesView; ensure accent_colour is valid")
|
||||
self.add_item(main_container)
|
||||
|
||||
main_container.add_item(ui.TextDisplay(f"**Level Roles for {guild.name}**"))
|
||||
title_display = ui.TextDisplay(f"**Level Roles for {guild.name}**")
|
||||
if title_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for title in ListLevelRolesView")
|
||||
main_container.add_item(title_display)
|
||||
|
||||
sep = ui.Separator(spacing=discord.SeparatorSpacing.small)
|
||||
if sep:
|
||||
main_container.add_item(sep)
|
||||
if sep is None:
|
||||
raise AssertionError("ui.Separator returned None in ListLevelRolesView")
|
||||
main_container.add_item(sep)
|
||||
|
||||
if not level_roles_data: # Should be caught by the check above, but good practice
|
||||
main_container.add_item(ui.TextDisplay("No level roles are registered for this server."))
|
||||
empty_display = ui.TextDisplay("No level roles are registered for this server.")
|
||||
if empty_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for empty message in ListLevelRolesView")
|
||||
main_container.add_item(empty_display)
|
||||
return
|
||||
|
||||
sorted_roles_items = sorted(level_roles_data.items())
|
||||
|
||||
for level, role_data_or_id in sorted_roles_items:
|
||||
role_section = ui.Section(accessory=None) # Explicitly pass accessory=None
|
||||
role_section.add_item(ui.TextDisplay(f"**Level {level}:**"))
|
||||
if role_section is None:
|
||||
raise AssertionError("ui.Section returned None in ListLevelRolesView")
|
||||
|
||||
level_title = ui.TextDisplay(f"**Level {level}:**")
|
||||
if level_title is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for level title in ListLevelRolesView")
|
||||
role_section.add_item(level_title)
|
||||
|
||||
if isinstance(role_data_or_id, dict): # Gendered roles
|
||||
for gender, role_id in role_data_or_id.items():
|
||||
role = guild.get_role(role_id)
|
||||
role_name = role.mention if role else f"Unknown Role (ID: {role_id})"
|
||||
role_section.add_item(ui.TextDisplay(f" - {gender.capitalize()}: {role_name}"))
|
||||
gender_display = ui.TextDisplay(f" - {gender.capitalize()}: {role_name}")
|
||||
if gender_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for gender role in ListLevelRolesView")
|
||||
role_section.add_item(gender_display)
|
||||
else: # Regular role
|
||||
role = guild.get_role(role_data_or_id)
|
||||
role_name = role.mention if role else f"Unknown Role (ID: {role_data_or_id})"
|
||||
role_section.add_item(ui.TextDisplay(f" {role_name}"))
|
||||
role_display = ui.TextDisplay(f" {role_name}")
|
||||
if role_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for regular role in ListLevelRolesView")
|
||||
role_section.add_item(role_display)
|
||||
|
||||
main_container.add_item(role_section)
|
||||
if level != sorted_roles_items[-1][0]: # Add separator if not the last item
|
||||
separator = ui.Separator(spacing=discord.SeparatorSpacing.small)
|
||||
if separator:
|
||||
main_container.add_item(separator)
|
||||
if separator is None:
|
||||
raise AssertionError("ui.Separator returned None between roles in ListLevelRolesView")
|
||||
main_container.add_item(separator)
|
||||
|
||||
|
||||
view = ListLevelRolesView(ctx.guild, self.level_roles[ctx.guild.id])
|
||||
@ -744,26 +799,25 @@ class LevelingCog(commands.Cog):
|
||||
def __init__(self, config_data: dict, prefix: str):
|
||||
super().__init__()
|
||||
|
||||
main_container = ui.Container(accent_colour=discord.Color.blue())
|
||||
main_container = ui.Container(accent_colour=discord.Colour.blue())
|
||||
if main_container is None:
|
||||
raise AssertionError("ui.Container returned None in XPConfigView; ensure accent_colour is valid")
|
||||
self.add_item(main_container)
|
||||
|
||||
title_text = ui.TextDisplay("**XP Configuration Settings**")
|
||||
if title_text:
|
||||
main_container.add_item(title_text)
|
||||
else:
|
||||
print("DEBUG: ui.TextDisplay returned None in XPConfigView (title)")
|
||||
if title_text is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for title in XPConfigView")
|
||||
main_container.add_item(title_text)
|
||||
|
||||
desc_text = ui.TextDisplay("Current XP settings for the leveling system:")
|
||||
if desc_text:
|
||||
main_container.add_item(desc_text)
|
||||
else:
|
||||
print("DEBUG: ui.TextDisplay returned None in XPConfigView (description)")
|
||||
if desc_text is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for description in XPConfigView")
|
||||
main_container.add_item(desc_text)
|
||||
|
||||
separator = ui.Separator(spacing=discord.SeparatorSpacing.small)
|
||||
if separator:
|
||||
main_container.add_item(separator)
|
||||
else:
|
||||
print("DEBUG: ui.Separator returned None in XPConfigView")
|
||||
if separator is None:
|
||||
raise AssertionError("ui.Separator returned None in XPConfigView")
|
||||
main_container.add_item(separator)
|
||||
|
||||
settings_to_display = [
|
||||
("XP Per Message", str(config_data["xp_per_message"])),
|
||||
@ -775,20 +829,24 @@ class LevelingCog(commands.Cog):
|
||||
|
||||
for name, value_str in settings_to_display:
|
||||
setting_section = ui.Section(accessory=None) # Explicitly pass accessory=None
|
||||
setting_section.add_item(ui.TextDisplay(f"**{name}:** {value_str}"))
|
||||
if setting_section is None:
|
||||
raise AssertionError("ui.Section returned None in XPConfigView")
|
||||
|
||||
setting_display = ui.TextDisplay(f"**{name}:** {value_str}")
|
||||
if setting_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for setting in XPConfigView")
|
||||
setting_section.add_item(setting_display)
|
||||
main_container.add_item(setting_section)
|
||||
|
||||
separator = ui.Separator(spacing=discord.SeparatorSpacing.small)
|
||||
if separator:
|
||||
main_container.add_item(separator)
|
||||
else:
|
||||
print("DEBUG: ui.Separator returned None in XPConfigView (bottom)")
|
||||
if separator is None:
|
||||
raise AssertionError("ui.Separator returned None at bottom in XPConfigView")
|
||||
main_container.add_item(separator)
|
||||
|
||||
help_text = ui.TextDisplay(f"Use {prefix}level config <setting> <value> to change a setting")
|
||||
if help_text:
|
||||
main_container.add_item(help_text)
|
||||
else:
|
||||
print("DEBUG: ui.TextDisplay returned None in XPConfigView (help)")
|
||||
if help_text is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for help text in XPConfigView")
|
||||
main_container.add_item(help_text)
|
||||
|
||||
# Attempt to get the prefix
|
||||
try:
|
||||
@ -1053,41 +1111,85 @@ class LevelingCog(commands.Cog):
|
||||
def __init__(self, created_roles_list: list, updated_roles_list: list, has_pronoun_roles_flag: bool):
|
||||
super().__init__()
|
||||
|
||||
main_container = ui.Container(accent_colour=discord.Color.gold())
|
||||
main_container = ui.Container(accent_colour=discord.Colour.gold())
|
||||
if main_container is None:
|
||||
raise AssertionError("ui.Container returned None in MedievalRolesSetupView; ensure accent_colour is valid")
|
||||
self.add_item(main_container)
|
||||
|
||||
main_container.add_item(ui.TextDisplay("**Medieval Level Roles Setup**"))
|
||||
main_container.add_item(ui.TextDisplay("The following roles have been set up for the medieval leveling system:"))
|
||||
title_display = ui.TextDisplay("**Medieval Level Roles Setup**")
|
||||
if title_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for title in MedievalRolesSetupView")
|
||||
main_container.add_item(title_display)
|
||||
|
||||
desc_display = ui.TextDisplay("The following roles have been set up for the medieval leveling system:")
|
||||
if desc_display is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for description in MedievalRolesSetupView")
|
||||
main_container.add_item(desc_display)
|
||||
|
||||
sep = ui.Separator(spacing=discord.SeparatorSpacing.small)
|
||||
if sep:
|
||||
main_container.add_item(sep)
|
||||
if sep is None:
|
||||
raise AssertionError("ui.Separator returned None in MedievalRolesSetupView")
|
||||
main_container.add_item(sep)
|
||||
|
||||
if created_roles_list:
|
||||
created_section = ui.Section(accessory=None) # Explicitly pass accessory=None
|
||||
created_section.add_item(ui.TextDisplay("**Created Roles:**"))
|
||||
if created_section is None:
|
||||
raise AssertionError("ui.Section returned None for created roles in MedievalRolesSetupView")
|
||||
|
||||
created_title = ui.TextDisplay("**Created Roles:**")
|
||||
if created_title is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for created roles title in MedievalRolesSetupView")
|
||||
created_section.add_item(created_title)
|
||||
|
||||
# For potentially long lists, join with newline. TextDisplay handles multiline.
|
||||
created_section.add_item(ui.TextDisplay("\n".join(created_roles_list) if created_roles_list else "None"))
|
||||
created_list = ui.TextDisplay("\n".join(created_roles_list) if created_roles_list else "None")
|
||||
if created_list is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for created roles list in MedievalRolesSetupView")
|
||||
created_section.add_item(created_list)
|
||||
main_container.add_item(created_section)
|
||||
|
||||
if created_roles_list: # Only add separator if there are created roles
|
||||
separator = ui.Separator(spacing=discord.SeparatorSpacing.small)
|
||||
if separator:
|
||||
main_container.add_item(separator)
|
||||
|
||||
if separator is None:
|
||||
raise AssertionError("ui.Separator returned None after created roles in MedievalRolesSetupView")
|
||||
main_container.add_item(separator)
|
||||
|
||||
if updated_roles_list:
|
||||
updated_section = ui.Section(accessory=None) # Explicitly pass accessory=None
|
||||
updated_section.add_item(ui.TextDisplay("**Updated Roles:**"))
|
||||
updated_section.add_item(ui.TextDisplay("\n".join(updated_roles_list) if updated_roles_list else "None"))
|
||||
if updated_section is None:
|
||||
raise AssertionError("ui.Section returned None for updated roles in MedievalRolesSetupView")
|
||||
|
||||
updated_title = ui.TextDisplay("**Updated Roles:**")
|
||||
if updated_title is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for updated roles title in MedievalRolesSetupView")
|
||||
updated_section.add_item(updated_title)
|
||||
|
||||
updated_list = ui.TextDisplay("\n".join(updated_roles_list) if updated_roles_list else "None")
|
||||
if updated_list is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for updated roles list in MedievalRolesSetupView")
|
||||
updated_section.add_item(updated_list)
|
||||
main_container.add_item(updated_section)
|
||||
|
||||
if updated_roles_list: # Only add separator if there are updated roles
|
||||
separator = ui.Separator(spacing=discord.SeparatorSpacing.small)
|
||||
if separator:
|
||||
main_container.add_item(separator)
|
||||
if separator is None:
|
||||
raise AssertionError("ui.Separator returned None after updated roles in MedievalRolesSetupView")
|
||||
main_container.add_item(separator)
|
||||
|
||||
gender_detection_section = ui.Section(accessory=None) # Explicitly pass accessory=None
|
||||
gender_detection_section.add_item(ui.TextDisplay("**Gender Detection:**"))
|
||||
if gender_detection_section is None:
|
||||
raise AssertionError("ui.Section returned None for gender detection in MedievalRolesSetupView")
|
||||
|
||||
gender_title = ui.TextDisplay("**Gender Detection:**")
|
||||
if gender_title is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for gender detection title in MedievalRolesSetupView")
|
||||
gender_detection_section.add_item(gender_title)
|
||||
|
||||
gender_text = "Gender-specific roles will be assigned based on pronoun roles." if has_pronoun_roles_flag else "No pronoun roles detected. Using default titles."
|
||||
gender_detection_section.add_item(ui.TextDisplay(gender_text))
|
||||
gender_desc = ui.TextDisplay(gender_text)
|
||||
if gender_desc is None:
|
||||
raise AssertionError("ui.TextDisplay returned None for gender detection description in MedievalRolesSetupView")
|
||||
gender_detection_section.add_item(gender_desc)
|
||||
main_container.add_item(gender_detection_section)
|
||||
|
||||
view = MedievalRolesSetupView(created_roles, updated_roles, has_pronoun_roles)
|
||||
|
Loading…
x
Reference in New Issue
Block a user