From 4d32a450a52bd32ffb5bc564ec13f35236ff3399 Mon Sep 17 00:00:00 2001 From: Snuffy2 Date: Mon, 7 Aug 2023 21:36:55 -0400 Subject: [PATCH] Send Check First & Separate Out Errors --- custom_components/healthchecksio/__init__.py | 79 ++++++++++++------- .../healthchecksio/config_flow.py | 74 ++++++++++++----- 2 files changed, 105 insertions(+), 48 deletions(-) diff --git a/custom_components/healthchecksio/__init__.py b/custom_components/healthchecksio/__init__.py index 2a4400f..e3333c4 100644 --- a/custom_components/healthchecksio/__init__.py +++ b/custom_components/healthchecksio/__init__.py @@ -4,27 +4,24 @@ For more details about this component, please refer to https://github.com/custom-components/healthchecksio """ -import os -import async_timeout import asyncio +import json +import os from datetime import timedelta + +import aiohttp from homeassistant.helpers.aiohttp_client import async_get_clientsession -import voluptuous as vol -from homeassistant import config_entries -import homeassistant.helpers.config_validation as cv -from homeassistant.helpers import discovery from homeassistant.util import Throttle - -from integrationhelper.const import CC_STARTUP_VERSION from integrationhelper import Logger +from integrationhelper.const import CC_STARTUP_VERSION from .const import ( - DOMAIN_DATA, DOMAIN, - ISSUE_URL, - REQUIRED_FILES, + DOMAIN_DATA, INTEGRATION_VERSION, + ISSUE_URL, OFFICIAL_SITE_ROOT, + REQUIRED_FILES, ) MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=300) @@ -95,28 +92,54 @@ def __init__(self, hass, api_key, check, self_hosted, site_root, ping_endpoint): @Throttle(MIN_TIME_BETWEEN_UPDATES) async def update_data(self): """Update data.""" - Logger("custom_components.healthchecksio").debug("Running update") + Logger("custom_components.healthchecksio").debug("Running Update") # This is where the main logic to update platform data goes. + verify_ssl = not self.self_hosted or self.site_root.startswith("https") + session = async_get_clientsession(self.hass, verify_ssl) + timeout10 = aiohttp.ClientTimeout(total=10) + headers = {"X-Api-Key": self.api_key} + if self.self_hosted: + check_url = f"{self.site_root}/{self.ping_endpoint}/{self.check}" + else: + check_url = f"https://hc-ping.com/{self.check}" + await asyncio.sleep(1) # needed for self-hosted instances try: - verify_ssl = not self.self_hosted or self.site_root.startswith("https") - session = async_get_clientsession(self.hass, verify_ssl) - headers = {"X-Api-Key": self.api_key} - async with async_timeout.timeout(10): - data = await session.get( - f"{self.site_root}/api/v1/checks/", headers=headers + check_response = await session.get(check_url, timeout=timeout10) + except (aiohttp.ClientError, asyncio.TimeoutError) as error: + Logger("custom_components.healthchecksio").error( + f"Could Not Send Check: {error}" + ) + else: + if check_response.ok: + Logger("custom_components.healthchecksio").debug( + f"Send Check HTTP Status Code: {check_response.status}" ) - self.hass.data[DOMAIN_DATA]["data"] = await data.json() - - if self.self_hosted: - check_url = f"{self.site_root}/{self.ping_endpoint}/{self.check}" - else: - check_url = f"https://hc-ping.com/{self.check}" - await asyncio.sleep(1) # needed for self-hosted instances - await session.get(check_url) - except Exception as error: # pylint: disable=broad-except + else: + Logger("custom_components.healthchecksio").error( + f"Error: Send Check HTTP Status Code: {check_response.status}" + ) + try: + data = await session.get( + f"{self.site_root}/api/v1/checks/", headers=headers, timeout=timeout10 + ) + self.hass.data[DOMAIN_DATA]["data"] = await data.json() + except (aiohttp.ClientError, asyncio.TimeoutError) as error: + Logger("custom_components.healthchecksio").error( + f"Could Not Update Data: {error}" + ) + except (ValueError, json.decoder.JSONDecodeError) as error: Logger("custom_components.healthchecksio").error( - f"Could not update data - {error}" + f"Data JSON Decode Error: {error}" ) + else: + if data.ok: + Logger("custom_components.healthchecksio").debug( + f"Get Data HTTP Status Code: {data.status}" + ) + else: + Logger("custom_components.healthchecksio").error( + f"Error: Get Data HTTP Status Code: {data.status}" + ) async def check_files(hass): diff --git a/custom_components/healthchecksio/config_flow.py b/custom_components/healthchecksio/config_flow.py index 217cf5c..d87fe4e 100644 --- a/custom_components/healthchecksio/config_flow.py +++ b/custom_components/healthchecksio/config_flow.py @@ -1,11 +1,13 @@ """Adds config flow for Blueprint.""" -import async_timeout import asyncio +import json from collections import OrderedDict + +import aiohttp import voluptuous as vol +from homeassistant import config_entries from homeassistant.helpers.aiohttp_client import async_get_clientsession from integrationhelper import Logger -from homeassistant import config_entries from .const import DOMAIN, DOMAIN_DATA, OFFICIAL_SITE_ROOT @@ -123,23 +125,55 @@ async def _test_credentials( self, api_key, check, self_hosted, site_root, ping_endpoint ): """Return true if credentials is valid.""" + Logger("custom_components.healthchecksio").debug("Testing Credentials") + verify_ssl = not self_hosted or site_root.startswith("https") + session = async_get_clientsession(self.hass, verify_ssl) + timeout10 = aiohttp.ClientTimeout(total=10) + headers = {"X-Api-Key": api_key} + if self_hosted: + check_url = f"{site_root}/{ping_endpoint}/{check}" + else: + check_url = f"https://hc-ping.com/{check}" + await asyncio.sleep(1) # needed for self-hosted instances try: - verify_ssl = not self_hosted or site_root.startswith("https") - session = async_get_clientsession(self.hass, verify_ssl) - headers = {"X-Api-Key": api_key} - async with async_timeout.timeout(10): - Logger("custom_components.healthchecksio").info("Checking API Key") - data = await session.get(f"{site_root}/api/v1/checks/", headers=headers) - self.hass.data[DOMAIN_DATA] = {"data": await data.json()} - - Logger("custom_components.healthchecksio").info("Checking Check ID") - if self_hosted: - check_url = f"{site_root}/{ping_endpoint}/{check}" - else: - check_url = f"https://hc-ping.com/{check}" - await asyncio.sleep(1) # needed for self-hosted instances - await session.get(check_url) + check_response = await session.get(check_url, timeout=timeout10) + except (aiohttp.ClientError, asyncio.TimeoutError) as error: + Logger("custom_components.healthchecksio").error( + f"Could Not Send Check: {error}" + ) + return False + else: + if check_response.ok: + Logger("custom_components.healthchecksio").debug( + f"Send Check HTTP Status Code: {check_response.status}" + ) + else: + Logger("custom_components.healthchecksio").error( + f"Error: Send Check HTTP Status Code: {check_response.status}" + ) + return False + try: + data = await session.get( + f"{site_root}/api/v1/checks/", headers=headers, timeout=timeout10 + ) + self.hass.data[DOMAIN_DATA] = {"data": await data.json()} + except (aiohttp.ClientError, asyncio.TimeoutError) as error: + Logger("custom_components.healthchecksio").error( + f"Could Not Update Data: {error}" + ) + return False + except (ValueError, json.decoder.JSONDecodeError) as error: + Logger("custom_components.healthchecksio").error( + f"Data JSON Decode Error: {error}" + ) + return False + else: + if not data.ok: + Logger("custom_components.healthchecksio").error( + f"Error: Get Data HTTP Status Code: {data.status}" + ) + return False + Logger("custom_components.healthchecksio").debug( + f"Get Data HTTP Status Code: {data.status}" + ) return True - except Exception as exception: # pylint: disable=broad-except - Logger("custom_components.healthchecksio").error(exception) - return False