Repository: home-assistant/core
File: homeassistant/components/portainer/button.py (Python)

Code before:

    _async_add_new_endpoints(
        [
            endpoint
            for endpoint in coordinator.data.values()
            if endpoint.id in coordinator.known_endpoints
        ]
    )
    _async_add_new_containers(
        [
            (endpoint, container)
            for endpoint in coordinator.data.values()
            for container in endpoint.containers.values()
        ]
    )


class PortainerBaseButton(ButtonEntity):
    """Common base for Portainer buttons. Basically to ensure the async_press logic isn't duplicated."""

    entity_description: PortainerButtonDescription
    coordinator: PortainerCoordinator

    async def _async_press_call(self) -> None:
        """Subclasses implement the actual press call, but we still need it here."""
        raise NotImplementedError

    async def async_press(self) -> None:
        """Trigger the Portainer button press service."""
        try:
            await self._async_press_call()
        except PortainerConnectionError as err:
            _LOGGER.exception("Connection error for button: %s", self.entity_id)
            raise HomeAssistantError(
                translation_domain=DOMAIN,
                translation_key="cannot_connect",
                translation_placeholders={"error": "See details in logs"},
            ) from err
        except PortainerAuthenticationError as err:
            _LOGGER.exception("Authentication error for button: %s", self.entity_id)
            raise HomeAssistantError(
                translation_domain=DOMAIN,
                translation_key="invalid_auth",
                translation_placeholders={"error": "See details in logs"},
            ) from err
        except PortainerTimeoutError as err:
            _LOGGER.exception("Timeout error for button: %s", self.entity_id)
            raise HomeAssistantError(
                translation_domain=DOMAIN,
                translation_key="timeout_connect",
                translation_placeholders={"error": "See details in logs"},

Review comment (refactor):
```suggestion
    @abstractmethod
    async def _async_press_call(self) -> None:
```
GitHub doesn't let me comment on all three lines, but IMO this is the nicer way of defining it, and remove the `NotImplementedError`

Code after:
    coordinator.new_containers_callbacks.append(_async_add_new_containers)

    _async_add_new_endpoints(
        [
            endpoint
            for endpoint in coordinator.data.values()
            if endpoint.id in coordinator.known_endpoints
        ]
    )
    _async_add_new_containers(
        [
            (endpoint, container)
            for endpoint in coordinator.data.values()
            for container in endpoint.containers.values()
        ]
    )


class PortainerBaseButton(ButtonEntity):
    """Common base for Portainer buttons. Basically to ensure the async_press logic isn't duplicated."""

    entity_description: PortainerButtonDescription
    coordinator: PortainerCoordinator

    @abstractmethod
    async def _async_press_call(self) -> None:
        """Abstract method used per Portainer button class."""

    async def async_press(self) -> None:
        """Trigger the Portainer button press service."""
        try:
            await self._async_press_call()
        except PortainerConnectionError as err:
            raise HomeAssistantError(
                translation_domain=DOMAIN,
                translation_key="cannot_connect_no_details",
            ) from err
        except PortainerAuthenticationError as err:
            raise HomeAssistantError(
                translation_domain=DOMAIN,
                translation_key="invalid_auth_no_details",
            ) from err
        except PortainerTimeoutError as err:
            raise HomeAssistantError(
                translation_domain=DOMAIN,
                translation_key="timeout_connect_no_details",
            ) from err


class PortainerEndpointButton(PortainerEndpointEntity, PortainerBaseButton):
    """Defines a Portainer endpoint button."""