Skip to content

Commit

Permalink
Update error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
spacemanspiff2007 committed Apr 2, 2024
1 parent 850dc1a commit ab18073
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/sml2mqtt/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '3.0.DEV-3'
__version__ = '3.0.DEV-4'
4 changes: 4 additions & 0 deletions src/sml2mqtt/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ def __init__(self, status: int):
super().__init__()
self.status: Final = status

def __str__(self):
return f'{self.__class__.__name__:s}: {self.status:d}'

@override
def log_msg(self, log: Logger):
log.error(f'Received http status {self.status}')
Expand All @@ -70,6 +73,7 @@ def __eq__(self, other):
return self.status == other.status
return NotImplemented


# ------------------------------------------------------------------------------------
# Value Processing Errors
# ------------------------------------------------------------------------------------
Expand Down
17 changes: 15 additions & 2 deletions src/sml2mqtt/sml_source/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from asyncio import sleep
from typing import TYPE_CHECKING, Final

from aiohttp import BasicAuth, ClientSession, ClientTimeout
from aiohttp import BasicAuth, ClientError, ClientSession, ClientTimeout

from sml2mqtt.__log__ import get_logger
from sml2mqtt.const import DeviceTask
Expand Down Expand Up @@ -83,16 +83,29 @@ async def _http_task(self):
self.device.on_source_failed(f'Could not create client session: {e}')
return None

interval: float = self.interval
com_errors: int = 0

while True:
await sleep(self.interval)
await sleep(interval)
interval = self.interval

try:
resp = await session.get(self.url, auth=self.auth, timeout=self.timeout)
if resp.status != 200:
raise HttpStatusError(resp.status) # noqa: TRY301

payload = await resp.read()
com_errors = 0
except Exception as e:
if isinstance(e, (ClientError, HttpStatusError)):
com_errors += 1
max_ignore: int = 3
if com_errors <= max_ignore:
interval = com_errors * self.interval / max_ignore
log.debug(f'Ignored {com_errors:d}/{max_ignore:d} {e}')
continue

self.device.on_error(e, show_traceback=False)
continue

Expand Down
10 changes: 9 additions & 1 deletion tests/test_source/test_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
from aioresponses import aioresponses
from tests.helper import wait_for_call

from sml2mqtt.errors import HttpStatusError
from sml2mqtt.sml_source.http import HttpSource, close_session


@pytest.fixture()
def source(device_mock):
return HttpSource(device_mock, 'http://localhost:39999', interval=0, auth=None, timeout=ClientTimeout(0.5))
return HttpSource(device_mock, 'http://localhost:39999', interval=0.020, auth=None, timeout=ClientTimeout(0.5))


@pytest.mark.skipif(sys.platform.lower() != "win32", reason="It's a mystery why this fails in CI")
Expand All @@ -37,6 +38,9 @@ async def test_400(device_mock, source):

with aioresponses() as m:
m.get(source.url, status=404)
m.get(source.url, status=404)
m.get(source.url, status=404)
m.get(source.url, status=404)

source.start()
try:
Expand All @@ -49,3 +53,7 @@ async def test_400(device_mock, source):
device_mock.on_error.assert_called_once()

await close_session()


def test_error_repr():
assert str(HttpStatusError(404)) == 'HttpStatusError: 404'

0 comments on commit ab18073

Please sign in to comment.