WS: Improve service calling errors (#23840)

* WS: Improve service calling errors

* Docstyle

* Types

* Update text
pull/23857/head
Paulus Schoutsen 2019-05-14 07:09:11 +02:00 committed by GitHub
parent 0d96095646
commit de1fd5a7fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 8 deletions

View File

@ -168,8 +168,14 @@ class ScriptEntity(ToggleEntity):
ATTR_NAME: self.script.name,
ATTR_ENTITY_ID: self.entity_id,
}, context=context)
await self.script.async_run(
kwargs.get(ATTR_VARIABLES), context)
try:
await self.script.async_run(
kwargs.get(ATTR_VARIABLES), context)
except Exception as err: # pylint: disable=broad-except
self.script.async_log_exception(
_LOGGER, "Error executing script {}".format(self.entity_id),
err)
raise err
async def async_turn_off(self, **kwargs):
"""Turn script off."""

View File

@ -120,17 +120,21 @@ async def handle_call_service(hass, connection, msg):
msg['domain'], msg['service'], msg.get('service_data'), blocking,
connection.context(msg))
connection.send_message(messages.result_message(msg['id']))
except ServiceNotFound:
connection.send_message(messages.error_message(
msg['id'], const.ERR_NOT_FOUND, 'Service not found.'))
except ServiceNotFound as err:
if err.domain == msg['domain'] and err.service == msg['service']:
connection.send_message(messages.error_message(
msg['id'], const.ERR_NOT_FOUND, 'Service not found.'))
else:
connection.send_message(messages.error_message(
msg['id'], const.ERR_HOME_ASSISTANT_ERROR, str(err)))
except HomeAssistantError as err:
connection.logger.exception(err)
connection.send_message(messages.error_message(
msg['id'], const.ERR_HOME_ASSISTANT_ERROR, '{}'.format(err)))
msg['id'], const.ERR_HOME_ASSISTANT_ERROR, str(err)))
except Exception as err: # pylint: disable=broad-except
connection.logger.exception(err)
connection.send_message(messages.error_message(
msg['id'], const.ERR_UNKNOWN_ERROR, '{}'.format(err)))
msg['id'], const.ERR_UNKNOWN_ERROR, str(err)))
@callback

View File

@ -75,3 +75,7 @@ class ServiceNotFound(HomeAssistantError):
self, "Service {}.{} not found".format(domain, service))
self.domain = domain
self.service = service
def __str__(self) -> str:
"""Return string representation."""
return "Unable to find service {}/{}".format(self.domain, self.service)

View File

@ -893,4 +893,4 @@ async def test_automation_with_error_in_script(hass, caplog):
hass.bus.async_fire('test_event')
await hass.async_block_till_done()
assert 'Service test.automation not found' in caplog.text
assert 'Service not found' in caplog.text

View File

@ -3,6 +3,8 @@
import unittest
from unittest.mock import patch, Mock
import pytest
from homeassistant.components import script
from homeassistant.components.script import DOMAIN
from homeassistant.const import (
@ -11,6 +13,7 @@ from homeassistant.const import (
from homeassistant.core import Context, callback, split_entity_id
from homeassistant.loader import bind_hass
from homeassistant.setup import setup_component, async_setup_component
from homeassistant.exceptions import ServiceNotFound
from tests.common import get_test_home_assistant
@ -300,3 +303,22 @@ async def test_shared_context(hass):
state = hass.states.get('script.test')
assert state is not None
assert state.context == context
async def test_logging_script_error(hass, caplog):
"""Test logging script error."""
assert await async_setup_component(hass, 'script', {
'script': {
'hello': {
'sequence': [
{'service': 'non.existing'}
]
}
}
})
with pytest.raises(ServiceNotFound) as err:
await hass.services.async_call('script', 'hello', blocking=True)
assert err.value.domain == 'non'
assert err.value.service == 'existing'
assert 'Error executing script' in caplog.text

View File

@ -67,6 +67,30 @@ async def test_call_service_not_found(hass, websocket_client):
assert msg['error']['code'] == const.ERR_NOT_FOUND
async def test_call_service_child_not_found(hass, websocket_client):
"""Test not reporting not found errors if it's not the called service."""
async def serv_handler(call):
await hass.services.async_call('non', 'existing')
hass.services.async_register('domain_test', 'test_service', serv_handler)
await websocket_client.send_json({
'id': 5,
'type': 'call_service',
'domain': 'domain_test',
'service': 'test_service',
'service_data': {
'hello': 'world'
}
})
msg = await websocket_client.receive_json()
assert msg['id'] == 5
assert msg['type'] == const.TYPE_RESULT
assert not msg['success']
assert msg['error']['code'] == const.ERR_HOME_ASSISTANT_ERROR
async def test_call_service_error(hass, websocket_client):
"""Test call service command with error."""
@callback