chore(profile): tolerate null/empty frames in walk_self_time
Some pyinstrument frame trees contain branches where an identifier is missing (typically at the very top or with certain async boundaries), which crashed the aggregator with a KeyError mid-run. Short-circuit on None frames and missing identifiers so a single ugly HTML no longer kills the summary of the other few hundred.
This commit is contained in:
@@ -57,7 +57,7 @@ def _is_synthetic(identifier: str) -> bool:
|
||||
return identifier in _SYNTHETIC or identifier.startswith(("[self]", "[await]"))
|
||||
|
||||
|
||||
def walk_self_time(frame: dict, acc: dict[str, float], parent_ident: str | None = None) -> None:
|
||||
def walk_self_time(frame: dict | None, acc: dict[str, float], parent_ident: str | None = None) -> None:
|
||||
"""
|
||||
Accumulate self-time by frame identifier.
|
||||
|
||||
@@ -65,7 +65,11 @@ def walk_self_time(frame: dict, acc: dict[str, float], parent_ident: str | None
|
||||
execution time. Rolling them into their parent ("self-time of X" vs. a
|
||||
global `[self]` bucket) is what gives us actionable per-function hotspots.
|
||||
"""
|
||||
ident = frame["identifier"]
|
||||
if not frame:
|
||||
return
|
||||
ident = frame.get("identifier")
|
||||
if not ident:
|
||||
return
|
||||
total = frame.get("time", 0.0)
|
||||
children = frame.get("children") or []
|
||||
child_total = sum(c.get("time", 0.0) for c in children)
|
||||
|
||||
Reference in New Issue
Block a user