Skip to content

GatewayDispatch._handle_message_generic assumes valid guild cache #82

@schlopp

Description

@schlopp

Summary

The method GatewayDispatch._handle_message_generic assumes that there is a cached guild for every message edited by a GuildMember, which could be false if the guild intent is turned off

Reproduction Steps

  1. Turn off guild intent
  2. Receive message edit event in a guild
  3. The message's author's guild (possibly) get's cached as None (even though its typed as Guild)

Minimal Reproducible Code

async def _handle_message_generic(
            self,
            data: payloads.Message) -> tuple[Message | None, Message] | None:
        """Handle message create and message edit."""

        # If there's no author, it's a webhook message
        if "author" not in data:
            return None

        # Get a message from cache (in case it's an edit or delete)
        cached = self.cache.get_message(data["id"])
        if cached is not None:
            current = copy(cached)
            message = cached._update(data)  # because a message already existed we don't need to add it to cache

            # If we got here, then a new author will not be created by the message,
            # so we're going to update the cache with our new data, as well as
            # write back some of our cached items into the object
            if isinstance(message.author, GuildMember):
                assert "member" in data
                assert "guild_id" in data
                message.author._update(data["member"])
                message.author._user._update(data["author"])
                guild = self.cache.get_guild(data["guild_id"])
                message.guild = guild
                message.author.guild = guild
            else:
                message.author._update(data["author"])

        # Create a new message
        # Doing this will try and read from cache, but afterwards will create
        # new objects (of things like User, GuildMember, and Channel).
        # If new objects are made, then we want to write these back to the
        # cache (apart from Channel, which isn't a full object).
        else:
            current = None
            message = Message(state=self.parent, data=data)
            self.cache.add_messages(message)  # message to cache

        return current, message

Expected Results

I expected message.author.guild not to be None

Actual Results

I expected message.author.guild (possibly) becomes None

Intents

no guilds intent

System Information

latest version of the rewrite branch

Checklist

  • I have searched the open issues for duplicates.
  • I have shown the entire traceback, if possible.
  • I have removed my token from display, if visible.

Additional Context

The issue takes place here

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions