Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't raise for asyncio cancelation #67

Merged
merged 1 commit into from
Feb 23, 2024
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
29 changes: 16 additions & 13 deletions pytraccar/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ async def _subscriber() -> None:
)

self._subscription_status = SubscriptionStatus.CONNECTED
while not connection.closed:
while (
not connection.closed
and self._subscription_status == SubscriptionStatus.CONNECTED
):
msg = await connection.receive()
if msg.type == aiohttp.WSMsgType.TEXT:
if not (data := msg.json()):
Expand Down Expand Up @@ -217,24 +220,24 @@ async def _subscriber() -> None:
headers={},
)
await _subscriber()
except TraccarConnectionException:
raise
except asyncio.TimeoutError as exception:
raise TraccarConnectionException(
"Timeout error connecting to Traccar"
) from exception
except asyncio.CancelledError:
raise TraccarConnectionException("Subscription cancelled") from None
except aiohttp.ClientError as exception:
raise TraccarConnectionException(
f"Could not communicate with Traccar - {exception}"
) from exception
self._subscription_status = SubscriptionStatus.DISCONNECTED
except Exception as exception: # pylint: disable=broad-except
self._subscription_status = SubscriptionStatus.ERROR
if isinstance(exception, TraccarConnectionException):
raise
if isinstance(exception, asyncio.TimeoutError):
raise TraccarConnectionException(
"Timeout error connecting to Traccar"
) from exception
if isinstance(exception, aiohttp.ClientError):
raise TraccarConnectionException(
f"Could not communicate with Traccar - {exception}"
) from exception
raise TraccarException(f"Unexpected error - {exception}") from exception
finally:
# Close the session if we can
# https://www.traccar.org/api-reference/#tag/Session/paths/~1session/delete
self._subscription_status = SubscriptionStatus.ERROR
with suppress(TraccarException):
await self._call_api(
"session",
Expand Down
35 changes: 22 additions & 13 deletions tests/test_subscription.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
"""Test subscription."""
import asyncio
from unittest.mock import patch
from aiohttp import WSMsgType

import aiohttp
import pytest
from aiohttp import WSMsgType

from pytraccar import (
ApiClient,
SubscriptionStatus,
TraccarConnectionException,
TraccarException,
SubscriptionStatus,
)
from tests.common import WSMessage

Expand Down Expand Up @@ -161,11 +162,6 @@ async def _handler(data):
TraccarConnectionException,
"Timeout error connecting to Traccar",
),
(
asyncio.CancelledError("boom"),
TraccarConnectionException,
"Subscription cancelled",
),
(
aiohttp.ClientError("boom"),
TraccarConnectionException,
Expand All @@ -187,11 +183,24 @@ async def test_subscription_exceptions(
):
"""Test subscription exceptions."""
assert api_client.subscription_status == SubscriptionStatus.DISCONNECTED
with patch("aiohttp.ClientSession.ws_connect", side_effect=side_effect):
with pytest.raises(
raises,
match=with_message,
):
await api_client.subscribe(None)
with patch(
"aiohttp.ClientSession.ws_connect", side_effect=side_effect
), pytest.raises(
raises,
match=with_message,
):
await api_client.subscribe(None)

assert api_client.subscription_status == SubscriptionStatus.ERROR


@pytest.mark.asyncio
async def test_subscription_cancelation(api_client: ApiClient):
"""Test subscription exceptions."""
assert api_client.subscription_status == SubscriptionStatus.DISCONNECTED
with patch(
"aiohttp.ClientSession.ws_connect", side_effect=asyncio.CancelledError("boom")
):
await api_client.subscribe(None)

assert api_client.subscription_status == SubscriptionStatus.DISCONNECTED
Loading