mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Fix profiler dumping object when repr fails (#67674)
* Fix profiler dumping object when repr fails * cover
This commit is contained in:
parent
ee38203e1d
commit
bfe94f1cc5
@ -8,6 +8,7 @@ import sys
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
from typing import Any
|
||||
|
||||
from guppy import hpy
|
||||
import objgraph
|
||||
@ -87,13 +88,24 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
persistent_notification.async_dismiss(hass, "profile_object_logging")
|
||||
domain_data.pop(LOG_INTERVAL_SUB)()
|
||||
|
||||
def _safe_repr(obj: Any) -> str:
|
||||
"""Get the repr of an object but keep going if there is an exception.
|
||||
|
||||
We wrap repr to ensure if one object cannot be serialized, we can
|
||||
still get the rest.
|
||||
"""
|
||||
try:
|
||||
return repr(obj)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
return f"Failed to serialize {type(obj)}"
|
||||
|
||||
def _dump_log_objects(call: ServiceCall) -> None:
|
||||
obj_type = call.data[CONF_TYPE]
|
||||
|
||||
_LOGGER.critical(
|
||||
"%s objects in memory: %s",
|
||||
obj_type,
|
||||
objgraph.by_type(obj_type),
|
||||
[_safe_repr(obj) for obj in objgraph.by_type(obj_type)],
|
||||
)
|
||||
|
||||
persistent_notification.create(
|
||||
|
@ -131,19 +131,31 @@ async def test_dump_log_object(hass, caplog):
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
class DumpLogDummy:
|
||||
def __init__(self, fail):
|
||||
self.fail = fail
|
||||
|
||||
def __repr__(self):
|
||||
if self.fail:
|
||||
raise Exception("failed")
|
||||
return "<DumpLogDummy success>"
|
||||
|
||||
obj1 = DumpLogDummy(False)
|
||||
obj2 = DumpLogDummy(True)
|
||||
|
||||
assert hass.services.has_service(DOMAIN, SERVICE_DUMP_LOG_OBJECTS)
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_DUMP_LOG_OBJECTS, {CONF_TYPE: "MockConfigEntry"}
|
||||
DOMAIN, SERVICE_DUMP_LOG_OBJECTS, {CONF_TYPE: "DumpLogDummy"}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "MockConfigEntry" in caplog.text
|
||||
assert "<DumpLogDummy success>" in caplog.text
|
||||
assert "Failed to serialize" in caplog.text
|
||||
del obj1
|
||||
del obj2
|
||||
caplog.clear()
|
||||
|
||||
assert await hass.config_entries.async_unload(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
async def test_log_thread_frames(hass, caplog):
|
||||
"""Test we can log thread frames."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user