feat(garmin): all-JSON wrapper protocol and log stream
Error responses from wrapper.py now carry error_type and traceback in
the protocol itself, logged as attrs on the Go side's per-call record.
wrapper.py's free-text stderr debug prints become JSON log lines
({level,msg,...attrs}); client.go parses that stream and re-emits it
through the application logger (level-mapped, source=garmin-wrapper),
wrapping any non-JSON line instead of passing it through raw. The
wrapper also survives malformed request lines and unserializable
results with JSON responses instead of crashing with a raw traceback.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -129,7 +129,13 @@ def test_call_propagates_garminconnect_exception_as_error():
|
||||
resp = wrapper.dispatch({
|
||||
"id": 9, "cmd": "call", "params": {"method": "get_activity_splits", "args": {"activity_id": "999"}},
|
||||
})
|
||||
assert resp == {"id": 9, "error": "not found"}
|
||||
assert resp["id"] == 9
|
||||
assert resp["error"] == "not found"
|
||||
# Failure detail travels in the protocol so the Go side can log one
|
||||
# complete structured record (no stderr correlation needed).
|
||||
assert resp["error_type"] == "Exception"
|
||||
assert "Exception: not found" in resp["traceback"]
|
||||
assert "not_found" not in resp
|
||||
|
||||
|
||||
def test_dispatch_unknown_cmd_is_error():
|
||||
@@ -280,7 +286,10 @@ def test_call_marks_not_found_error_specifically():
|
||||
resp = wrapper.dispatch({
|
||||
"id": 11, "cmd": "call", "params": {"method": "get_workout_by_id", "args": {"workout_id": "999"}},
|
||||
})
|
||||
assert resp == {"id": 11, "error": "API Error 404", "not_found": True}
|
||||
assert resp["id"] == 11
|
||||
assert resp["error"] == "API Error 404"
|
||||
assert resp["not_found"] is True
|
||||
assert resp["error_type"] == "GarminConnectNotFoundError"
|
||||
|
||||
|
||||
def test_call_does_not_mark_other_errors_as_not_found():
|
||||
@@ -290,4 +299,6 @@ def test_call_does_not_mark_other_errors_as_not_found():
|
||||
resp = wrapper.dispatch({
|
||||
"id": 12, "cmd": "call", "params": {"method": "get_workout_by_id", "args": {"workout_id": "999"}},
|
||||
})
|
||||
assert resp == {"id": 12, "error": "rate limited"}
|
||||
assert resp["id"] == 12
|
||||
assert resp["error"] == "rate limited"
|
||||
assert "not_found" not in resp
|
||||
|
||||
Reference in New Issue
Block a user