# Buggy code
async def backfill(
    self, dest: str, room_id: str, limit: int, extremities: Iterable[str]
) -> List[EventBase]:
    """Requests some more historic PDUs for the given room from the
    given destination server.

    Args:
        dest (str): The remote homeserver to ask.
        room_id (str): The room_id to backfill.
        limit (int): The maximum number of events to return.
        extremities (list): our current backwards extremities, to backfill from
    """
    logger.debug("backfill extrem=%s", extremities)

    # If there are no extremeties then we've (probably) reached the start.
    if not extremities:
        return

    transaction_data = await self.transport_layer.backfill(
        dest, room_id, extremities, limit
    )

    logger.debug("backfill transaction_data=%r", transaction_data)

    room_version = await self.store.get_room_version(room_id)

    pdus = [
        event_from_pdu_json(p, room_version, outlier=False)
        for p in transaction_data["pdus"]
    ]

    # FIXME: We should handle signature failures more gracefully.
    pdus[:] = await make_deferred_yieldable(
        defer.gatherResults(
            self._check_sigs_and_hashes(room_version.identifier, pdus),
            consumeErrors=True,
        ).addErrback(unwrapFirstError)
    )

    return pdus


# Traceback (AttributeError)
2020-02-24 14:00:10,088 - synapse.federation.federation_client - 421 - WARNING - POST-1957- Failed to send_join via matrix.org
...
Traceback (most recent call last):
File "/home/synapse/matrixtest/synapse/federation/federation_client.py", line 402, in _try_destination_list
res = await callback(destination)
File "/home/synapse/matrixtest/synapse/federation/federation_client.py", line 589, in send_request
valid_pdus_map = {p.event_id: p for p in valid_pdus}
File "/home/synapse/matrixtest/synapse/federation/federation_client.py", line 589, in <dictcomp>
valid_pdus_map = {p.event_id: p for p in valid_pdus}
AttributeError: 'coroutine' object has no attribute 'event_id'
2020-02-24 14:00:10,154 - synapse.http.server - 81 - INFO - POST-1957- <SynapseRequest at 0x7ff1bf3efd30 method='POST' uri='/_matrix/client/r0/join/%23synapse%3Amatrix.org' clientproto='HTTP/1.1' site=8447> SynapseError: 502 - Failed to send_join via any server

# Fixed code
async def backfill(
    self, dest: str, room_id: str, limit: int, extremities: Iterable[str]
) -> Optional[List[EventBase]]:
    """Requests some more historic PDUs for the given room from the
    given destination server.

    Args:
        dest (str): The remote homeserver to ask.
        room_id (str): The room_id to backfill.
        limit (int): The maximum number of events to return.
        extremities (list): our current backwards extremities, to backfill from
    """
    logger.debug("backfill extrem=%s", extremities)

    # If there are no extremities then we've (probably) reached the start.
    if not extremities:
        return None

    transaction_data = await self.transport_layer.backfill(
        dest, room_id, extremities, limit
    )

    logger.debug("backfill transaction_data=%r", transaction_data)

    room_version = await self.store.get_room_version(room_id)

    pdus = [
        event_from_pdu_json(p, room_version, outlier=False)
        for p in transaction_data["pdus"]
    ]

    # FIXME: We should handle signature failures more gracefully.
    pdus[:] = await make_deferred_yieldable(
        defer.gatherResults(
            self._check_sigs_and_hashes(room_version.identifier, pdus),
            consumeErrors=True,
        ).addErrback(unwrapFirstError)
    )

    return pdus