Preserve native K1 error causes and distinguish Wi-Fi actions
This commit is contained in:
@@ -37,6 +37,29 @@ ATTESTATION = {
|
||||
}
|
||||
|
||||
|
||||
def failure_locations(error: BaseException) -> str:
|
||||
"""Bounded causal stack, excluding messages, source lines and frame locals.
|
||||
|
||||
The facade deliberately wraps native transport errors. Logging only the
|
||||
outer stack loses the actual OS failure boundary on journalled responses.
|
||||
"""
|
||||
chain: list[str] = []
|
||||
seen: set[int] = set()
|
||||
current: BaseException | None = error
|
||||
while current is not None and id(current) not in seen and len(chain) < 6:
|
||||
seen.add(id(current))
|
||||
frames = list(traceback.walk_tb(current.__traceback__))[-10:]
|
||||
locations = ";".join(
|
||||
f"{Path(frame.f_code.co_filename).name}:{frame.f_code.co_name}:{line}"
|
||||
for frame, line in frames
|
||||
)
|
||||
chain.append(f"{type(current).__name__}[{locations}]")
|
||||
current = current.__cause__ or (
|
||||
None if current.__suppress_context__ else current.__context__
|
||||
)
|
||||
return " <- ".join(chain)
|
||||
|
||||
|
||||
class NodeEnrollmentRejected(ValueError):
|
||||
"""A host admission failure proven to precede any device invocation."""
|
||||
|
||||
@@ -152,14 +175,11 @@ class NodeBridge:
|
||||
# results, so the HTTP exception logger never sees them. Record
|
||||
# only source locations here; exception text may contain a frame.
|
||||
logging.getLogger(__name__).warning(
|
||||
"K1 journalled invocation failed: action=%s operation=%s exception=%s locations=%s",
|
||||
"K1 journalled invocation failed: action=%s operation=%s exception=%s chain=%s",
|
||||
action,
|
||||
identifier,
|
||||
type(error).__name__,
|
||||
";".join(
|
||||
f"{Path(frame.filename).name}:{frame.name}:{frame.lineno}"
|
||||
for frame in traceback.extract_tb(error.__traceback__)[-10:]
|
||||
),
|
||||
failure_locations(error),
|
||||
)
|
||||
# Read the exact result after a failure; never repeat an invocation
|
||||
# or interpret an exception as evidence that a command was unsent.
|
||||
@@ -346,15 +366,12 @@ def create_app(repository_root: Path):
|
||||
# text, source lines, local variables, payloads or credentials.
|
||||
action = body.get("action") if isinstance(body, dict) else None
|
||||
logging.getLogger(__name__).warning(
|
||||
"K1 operation failed: action=%s exception=%s locations=%s",
|
||||
"K1 operation failed: action=%s exception=%s chain=%s",
|
||||
action
|
||||
if isinstance(action, str) and action in {"scan", "networks", "connect", "verify"}
|
||||
else "invalid",
|
||||
type(error).__name__,
|
||||
";".join(
|
||||
f"{Path(frame.filename).name}:{frame.name}:{frame.lineno}"
|
||||
for frame in traceback.extract_tb(error.__traceback__)[-8:]
|
||||
),
|
||||
failure_locations(error),
|
||||
)
|
||||
return JSONResponse(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user