Fix mqtt callback exception logging (#118138)

* Fix mqtt callback exception logging

* Improve code

* Add test
This commit is contained in:
Jan Bouwhuis 2024-05-25 22:46:33 +02:00 committed by GitHub
parent 569763b7a8
commit 521ed0a220
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 3 deletions

View File

@ -835,8 +835,13 @@ class MQTT:
msg: ReceiveMessage,
) -> str:
"""Return a string with the exception message."""
# if msg_callback is a partial we return the name of the first argument
if isinstance(msg_callback, partial):
call_back_name = getattr(msg_callback.args[0], "__name__") # type: ignore[unreachable]
else:
call_back_name = getattr(msg_callback, "__name__")
return (
f"Exception in {msg_callback.__name__} when handling msg on "
f"Exception in {call_back_name} when handling msg on "
f"'{msg.topic}': '{msg.payload}'" # type: ignore[str-bytes-safe]
)

View File

@ -4,6 +4,7 @@ import asyncio
from collections.abc import Generator
from copy import deepcopy
from datetime import datetime, timedelta
from functools import partial
import json
import logging
import socket
@ -2912,8 +2913,8 @@ async def test_message_callback_exception_gets_logged(
await mqtt_mock_entry()
@callback
def bad_handler(*args) -> None:
"""Record calls."""
def bad_handler(msg: ReceiveMessage) -> None:
"""Handle callback."""
raise ValueError("This is a bad message callback")
await mqtt.async_subscribe(hass, "test-topic", bad_handler)
@ -2926,6 +2927,40 @@ async def test_message_callback_exception_gets_logged(
)
@pytest.mark.no_fail_on_log_exception
async def test_message_partial_callback_exception_gets_logged(
hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
mqtt_mock_entry: MqttMockHAClientGenerator,
) -> None:
"""Test exception raised by message handler."""
await mqtt_mock_entry()
@callback
def bad_handler(msg: ReceiveMessage) -> None:
"""Handle callback."""
raise ValueError("This is a bad message callback")
def parial_handler(
msg_callback: MessageCallbackType,
attributes: set[str],
msg: ReceiveMessage,
) -> None:
"""Partial callback handler."""
msg_callback(msg)
await mqtt.async_subscribe(
hass, "test-topic", partial(parial_handler, bad_handler, {"some_attr"})
)
async_fire_mqtt_message(hass, "test-topic", "test")
await hass.async_block_till_done()
assert (
"Exception in bad_handler when handling msg on 'test-topic':"
" 'test'" in caplog.text
)
async def test_mqtt_ws_subscription(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,