# Buggy code
def _event_match(self, condition: dict, user_id: str) -> bool:
    pattern = condition.get("pattern", None)

    if not pattern:
        pattern_type = condition.get("pattern_type", None)
        if pattern_type == "user_id":
            pattern = user_id
        elif pattern_type == "user_localpart":
            pattern = UserID.from_string(user_id).localpart

    if not pattern:
        logger.warning("event_match condition with no pattern")
        return False

    # XXX: optimisation: cache our pattern regexps
    if condition["key"] == "content.body":
        body = self._event.content.get("body", None)
        if not body:
            return False

        return _glob_matches(pattern, body, word_boundary=True)
    else:
        haystack = self._get_value(condition["key"])
        if haystack is None:
            return False

        return _glob_matches(pattern, haystack)


# Traceback (TypeError)
2020-06-15 19:00:06,270 - synapse.federation.federation_server - 290 - ERROR - PUT-1359406-$1592244001432863GBGGz:matrix.org- Failed to handle PDU $1592244001432863GBGGz:matrix.org
...
Traceback (most recent call last):
File "/opt/synapse/synapse/synapse/federation/federation_server.py", line 279, in process_pdus_for_room
await self._handle_received_pdu(origin, pdu)
File "/opt/synapse/synapse/synapse/federation/federation_server.py", line 658, in _handle_received_pdu
await self.handler.on_receive_pdu(origin, pdu, sent_to_us_directly=True)
File "/opt/synapse/synapse/synapse/handlers/federation.py", line 412, in on_receive_pdu
await self._process_received_pdu(origin, pdu, state=state)
File "/opt/synapse/synapse/synapse/handlers/federation.py", line 690, in _process_received_pdu
context = await self._handle_new_event(origin, event, state=state)
File "/opt/synapse/synapse/synapse/handlers/federation.py", line 1841, in _handle_new_event
event, context
File "/opt/synapse/synapse/synapse/push/action_generator.py", line 43, in handle_push_actions_for_event
yield self.bulk_evaluator.action_for_event_by_user(event, context)
File "/opt/synapse/env3/lib/python3.5/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
result = g.send(result)
File "/opt/synapse/synapse/synapse/push/bulk_push_rule_evaluator.py", line 190, in action_for_event_by_user
evaluator, rule["conditions"], uid, display_name, condition_cache
File "/opt/synapse/synapse/synapse/push/bulk_push_rule_evaluator.py", line 215, in _condition_checker
res = evaluator.matches(cond, uid, display_name)
File "/opt/synapse/synapse/synapse/push/push_rule_evaluator.py", line 107, in matches
return self._contains_display_name(display_name)
File "/opt/synapse/synapse/synapse/push/push_rule_evaluator.py", line 161, in _contains_display_name
return r.search(body)
TypeError: expected string or bytes-like object
2020-06-15 19:00:06,285 - synapse.logging.context - 396 - WARNING - PUT-1359406-$1592244001432863GBGGz:matrix.org- Re-starting finished log context PUT-1359406-$1592244001432863GBGGz:matrix.org

# Fixed code
def _event_match(self, condition: dict, user_id: str) -> bool:
    pattern = condition.get("pattern", None)

    if not pattern:
        pattern_type = condition.get("pattern_type", None)
        if pattern_type == "user_id":
            pattern = user_id
        elif pattern_type == "user_localpart":
            pattern = UserID.from_string(user_id).localpart

    if not pattern:
        logger.warning("event_match condition with no pattern")
        return False

    # XXX: optimisation: cache our pattern regexps
    if condition["key"] == "content.body":
        body = self._event.content.get("body", None)
        if not body or not isinstance(body, str):
            return False

        return _glob_matches(pattern, body, word_boundary=True)
    else:
        haystack = self._get_value(condition["key"])
        if haystack is None:
            return False

        return _glob_matches(pattern, haystack)