<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def connection_lost(self, exc: Optional[Exception]) -> None: """ 7.1.4. The WebSocket Connection is Closed. """

        logger.debug("%s - event = connection_lost(%s)", self.side, exc)
        self.state = State.CLOSED
        logger.debug("%s - state = CLOSED", self.side)
        if not hasattr(self, "close_code"):
            self.close_code = 1006
        if not hasattr(self, "close_reason"):
            self.close_reason = ""
        logger.debug(
            "%s x code = %d, reason = %s",
            self.side,
            self.close_code,
            self.close_reason or "[no reason]",
        )
        self.abort_keepalive_pings()
        # If self.connection_lost_waiter isn't pending, that's a bug, because:
        # - it's set only here in connection_lost() which is called only once;
        # - it must never be canceled.
        self.connection_lost_waiter.set_result(None)
        super().connection_lost(exc)