WS: Improve service calling errors (#23840)
* WS: Improve service calling errors * Docstyle * Types * Update textpull/23857/head
parent
0d96095646
commit
de1fd5a7fa
|
@ -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."""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue