From a8e9ccbf1a88d1a9e1c04da36a16910940a9fe19 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 11 Jun 2020 22:56:00 -0700 Subject: [PATCH] Improve cloud error handling (#36670) --- homeassistant/components/cloud/http_api.py | 16 ++++++++++------ tests/components/cloud/test_http_api.py | 12 ++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/cloud/http_api.py b/homeassistant/components/cloud/http_api.py index c3809f76b8c..6710d8682e2 100644 --- a/homeassistant/components/cloud/http_api.py +++ b/homeassistant/components/cloud/http_api.py @@ -71,6 +71,8 @@ _CLOUD_ERRORS = { HTTP_INTERNAL_SERVER_ERROR, "Remote UI not compatible with 127.0.0.1/::1 as trusted proxies.", ), + asyncio.TimeoutError: (502, "Unable to reach the Home Assistant cloud."), + aiohttp.ClientError: (HTTP_INTERNAL_SERVER_ERROR, "Error making internal request",), } @@ -120,11 +122,6 @@ async def async_setup(hass): HTTP_BAD_REQUEST, "Password change required.", ), - asyncio.TimeoutError: (502, "Unable to reach the Home Assistant cloud."), - aiohttp.ClientError: ( - HTTP_INTERNAL_SERVER_ERROR, - "Error making internal request", - ), } ) @@ -166,10 +163,17 @@ def _ws_handle_cloud_errors(handler): def _process_cloud_exception(exc, where): """Process a cloud exception.""" - err_info = _CLOUD_ERRORS.get(exc.__class__) + err_info = None + + for err, value_info in _CLOUD_ERRORS.items(): + if isinstance(exc, err): + err_info = value_info + break + if err_info is None: _LOGGER.exception("Unexpected error processing request for %s", where) err_info = (502, f"Unexpected error: {exc}") + return err_info diff --git a/tests/components/cloud/test_http_api.py b/tests/components/cloud/test_http_api.py index df506d2d8fc..0b5aec2818e 100644 --- a/tests/components/cloud/test_http_api.py +++ b/tests/components/cloud/test_http_api.py @@ -2,6 +2,7 @@ import asyncio from ipaddress import ip_network +import aiohttp from hass_nabucasa import thingtalk from hass_nabucasa.auth import Unauthenticated, UnknownError from hass_nabucasa.const import STATE_CONNECTED @@ -279,6 +280,17 @@ async def test_forgot_password_view_unknown_error(mock_cognito, cloud_client): assert req.status == 502 +async def test_forgot_password_view_aiohttp_error(mock_cognito, cloud_client): + """Test unknown error while logging out.""" + mock_cognito.initiate_forgot_password.side_effect = aiohttp.ClientResponseError( + Mock(), Mock() + ) + req = await cloud_client.post( + "/api/cloud/forgot_password", json={"email": "hello@bla.com"} + ) + assert req.status == 500 + + async def test_resend_confirm_view(mock_cognito, cloud_client): """Test logging out.""" req = await cloud_client.post(