From f32d17d924c3a5f0a6acdfd5249c21d34d8bdd5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Sun, 30 Aug 2020 17:53:10 +0200 Subject: [PATCH] Format API error messages (#1997) --- supervisor/addons/addon.py | 2 +- supervisor/api/utils.py | 12 ++++++------ supervisor/docker/__init__.py | 2 +- supervisor/utils/log_format.py | 15 +++++++++++++++ tests/utils/test_log_format.py | 11 +++++++++++ 5 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 supervisor/utils/log_format.py create mode 100644 tests/utils/test_log_format.py diff --git a/supervisor/addons/addon.py b/supervisor/addons/addon.py index fae0bc346..ea4426d56 100644 --- a/supervisor/addons/addon.py +++ b/supervisor/addons/addon.py @@ -552,7 +552,7 @@ class Addon(AddonModel): await self.instance.run() except DockerAPIError as err: self.state = AddonState.ERROR - raise AddonsError() from err + raise AddonsError(err) from None else: self.state = AddonState.STARTED diff --git a/supervisor/api/utils.py b/supervisor/api/utils.py index 8c64c3204..9c5fceefd 100644 --- a/supervisor/api/utils.py +++ b/supervisor/api/utils.py @@ -1,6 +1,5 @@ """Init file for Supervisor util for RESTful API.""" import json -import logging from typing import Any, Dict, List, Optional from aiohttp import web @@ -19,8 +18,7 @@ from ..const import ( RESULT_OK, ) from ..exceptions import APIError, APIForbidden, HassioError - -_LOGGER: logging.Logger = logging.getLogger(__name__) +from ..utils.log_format import format_message def excract_supervisor_token(request: web.Request) -> Optional[str]: @@ -61,8 +59,10 @@ def api_process(method): answer = await method(api, *args, **kwargs) except (APIError, APIForbidden) as err: return api_return_error(message=str(err)) - except HassioError: - return api_return_error(message="Unknown Error, see logs") + except HassioError as err: + return api_return_error( + message=str(err) if err else "Unknown Error, see logs" + ) if isinstance(answer, dict): return api_return_ok(data=answer) @@ -103,7 +103,7 @@ def api_process_raw(content): def api_return_error(message: Optional[str] = None) -> web.Response: """Return an API error message.""" return web.json_response( - {JSON_RESULT: RESULT_ERROR, JSON_MESSAGE: message}, status=400 + {JSON_RESULT: RESULT_ERROR, JSON_MESSAGE: format_message(message)}, status=400 ) diff --git a/supervisor/docker/__init__.py b/supervisor/docker/__init__.py index 03a55ba59..ec47efb26 100644 --- a/supervisor/docker/__init__.py +++ b/supervisor/docker/__init__.py @@ -149,7 +149,7 @@ class DockerAPI: container.start() except (docker.errors.DockerException, requests.RequestException) as err: _LOGGER.error("Can't start %s: %s", name, err) - raise DockerAPIError() from err + raise DockerAPIError(err) from None # Update metadata with suppress(docker.errors.DockerException, requests.RequestException): diff --git a/supervisor/utils/log_format.py b/supervisor/utils/log_format.py new file mode 100644 index 000000000..c55d4e66d --- /dev/null +++ b/supervisor/utils/log_format.py @@ -0,0 +1,15 @@ +"""Custom log messages.""" +import re + +RE_BIND_FAILED = re.compile(r".*Bind for.*:(\d*) failed: port is already allocated.*") + + +def format_message(message: str) -> str: + """Return a formated message if it's known.""" + match = RE_BIND_FAILED.match(message) + if match: + return ( + f"Port '{match.group(1)}' is already in use by something else on the host." + ) + + return message diff --git a/tests/utils/test_log_format.py b/tests/utils/test_log_format.py new file mode 100644 index 000000000..d03e22849 --- /dev/null +++ b/tests/utils/test_log_format.py @@ -0,0 +1,11 @@ +"""Tests for message formater.""" +from supervisor.utils.log_format import format_message + + +def test_format_message(): + """Tests for message formater.""" + message = '500 Server Error: Internal Server Error: Bind for 0.0.0.0:80 failed: port is already allocated")' + assert ( + format_message(message) + == "Port '80' is already in use by something else on the host." + )