Handle exception chain on addon boot (#2063)

* Handle exception chain on addon boot

* fix import

* Add tests
This commit is contained in:
Pascal Vizeli 2020-09-17 12:01:48 +02:00 committed by GitHub
parent 7633d26806
commit 78f63380f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 7 deletions

View File

@ -15,11 +15,11 @@ from ..exceptions import (
DockerAPIError,
DockerError,
DockerNotFound,
DockerRequestError,
HomeAssistantAPIError,
HostAppArmorError,
)
from ..store.addon import AddonStore
from ..utils import check_exception_chain
from .addon import Addon
from .data import AddonsData
@ -102,11 +102,13 @@ class AddonManager(CoreSysAttributes):
for addon in tasks:
try:
await addon.start()
except DockerRequestError:
pass
except (AddonConfigurationError, DockerAPIError, DockerNotFound):
addon.boot = AddonBoot.MANUAL
addon.save_persist()
except AddonsError as err:
# Check if there is an system/user issue
if check_exception_chain(
err, (DockerAPIError, DockerNotFound, AddonConfigurationError)
):
addon.boot = AddonBoot.MANUAL
addon.save_persist()
except Exception as err: # pylint: disable=broad-except
self.sys_capture_exception(err)
else:

View File

@ -5,7 +5,7 @@ from ipaddress import IPv4Address
import logging
import re
import socket
from typing import Optional
from typing import Any, Optional
_LOGGER: logging.Logger = logging.getLogger(__name__)
@ -107,3 +107,17 @@ def check_port(address: IPv4Address, port: int) -> bool:
except OSError:
pass
return False
def check_exception_chain(err: Exception, object_type: Any) -> bool:
"""Check if exception chain include sub exception.
It's not full recursive because we need mostly only access to the latest.
"""
if issubclass(type(err), object_type):
return True
if not err.__context__:
return False
return check_exception_chain(err.__context__, object_type)

View File

@ -0,0 +1,36 @@
"""Test exception helpers."""
from supervisor.utils import check_exception_chain
def test_simple_chain_exception():
"""Test simple chain of excepiton."""
try:
raise ValueError()
except ValueError as err:
assert check_exception_chain(err, ValueError)
def test_simple_nested_chain_exception():
"""Test simple nested chain of excepiton."""
try:
try:
raise ValueError()
except ValueError as err:
raise KeyError() from err
except KeyError as err:
assert check_exception_chain(err, ValueError)
def test_list_nested_chain_exception():
"""Test list nested chain of excepiton."""
try:
try:
raise ValueError()
except ValueError as err:
raise KeyError() from err
except KeyError as err:
assert check_exception_chain(err, (ValueError, OSError))