Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/linkplay/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
"""This module defines custom exceptions for the LinkPlay integration."""


class LinkPlayException(Exception):
pass
"""Base exception for LinkPlay errors."""


class LinkPlayRequestException(LinkPlayException):
pass
"""Exception raised for errors in LinkPlay requests."""


class LinkPlayRequestCancelledException(LinkPlayException):
"""Exception raised when a LinkPlay request is cancelled."""


class LinkPlayInvalidDataException(LinkPlayException):
"""Exception raised for invalid data received from LinkPlay endpoints."""

def __init__(self, message: str = "Invalid data received", data: str | None = None):
super().__init__(message)
self.data = data
33 changes: 25 additions & 8 deletions src/linkplay/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,25 @@

import aiofiles
import async_timeout
from aiohttp import ClientError, ClientSession, TCPConnector
from aiohttp import ClientError, ClientSession, ClientTimeout, TCPConnector
from appdirs import AppDirs
from deprecated import deprecated

from linkplay.consts import (
API_ENDPOINT,
API_TIMEOUT,
LOGGER,
MTLS_CERTIFICATE_CONTENTS,
TCP_MESSAGE_LENGTH,
EqualizerMode,
PlayerAttribute,
PlayingStatus,
)
from linkplay.exceptions import LinkPlayInvalidDataException, LinkPlayRequestException
from linkplay.exceptions import (
LinkPlayInvalidDataException,
LinkPlayRequestCancelledException,
LinkPlayRequestException,
)


async def session_call_api(endpoint: str, session: ClientSession, command: str) -> str:
Expand All @@ -45,18 +50,29 @@ async def session_call_api(endpoint: str, session: ClientSession, command: str)
try:
async with async_timeout.timeout(API_TIMEOUT):
response = await session.get(url)

except (asyncio.TimeoutError, ClientError, asyncio.CancelledError) as error:
if response.status != HTTPStatus.OK:
raise LinkPlayRequestException(
f"Unexpected HTTPStatus {response.status} received from '{url}'"
)
return await response.text()

except ClientError as error:
LOGGER.warning("ClientError for %s: %s", url, error)
raise LinkPlayRequestException(
f"{error} error requesting data from '{url}'"
) from error

if response.status != HTTPStatus.OK:
except asyncio.TimeoutError as error:
LOGGER.warning("Timeout for %s: %s", url, error)
raise LinkPlayRequestException(
f"Unexpected HTTPStatus {response.status} received from '{url}'"
)
f"{error} error requesting data from '{url}'"
) from error

return await response.text()
except asyncio.CancelledError as error:
LOGGER.warning("Cancelled for %s: %s", url, error)
raise LinkPlayRequestCancelledException(
f"{error} error requesting data from '{url}'"
) from error


async def session_call_api_json(
Expand All @@ -81,6 +97,7 @@ async def session_call_api_json(
return json.loads(result) # type: ignore
except json.JSONDecodeError as jsonexc:
url = API_ENDPOINT.format(endpoint, command)
LOGGER.warning("Unexpected json for %s: %s", url, jsonexc)
raise LinkPlayInvalidDataException(
message=f"Unexpected JSON ({result}) received from '{url}'", data=result
) from jsonexc
Expand Down