-
Notifications
You must be signed in to change notification settings - Fork 61
Description
Description
ROS2 ActionClient fails with KeyError when receiving action results from rosbridge
To Reproduce
python
import roslibpy
from roslibpy import ActionClient
client = roslibpy.Ros(host='localhost', port=9090)
client.run()
action = ActionClient(
client,
'/do_objective',
'moveit_studio_sdk_msgs/action/DoObjectiveSequence'
)
def on_result(result):
print(f"Result: {result}")
def on_feedback(feedback):
print(f"Feedback: {feedback}")
def on_error(error):
print(f"Error: {error}")
goal = {"objective_name": "test"}
goal_id = action.send_goal(goal, on_result, on_feedback, on_error)
# Wait for result...
Error Output
Exception on start_listening while trying to handle message received.It could indicate a bug in user code on message handlers. Message skipped.
Traceback (most recent call last):
File "/usr/local/lib/python3.12/dist-packages/roslibpy/comm/comm_autobahn.py", line 40, in onMessage
self.on_message(payload)
File "/usr/local/lib/python3.12/dist-packages/roslibpy/comm/comm.py", line 49, in on_message
handler(message)
File "/usr/local/lib/python3.12/dist-packages/roslibpy/comm/comm.py", line 166, in _handle_action_result
LOGGER.debug("Received Action result with status: %s", message["status"])
~~~~~~~^^^^^^^^^^
KeyError: 'status'
Expected behavior
The message structure from rosbridge is:
{
"values": {
"status": 4, // <-- Status is HERE
"result": {...}
}
}
But roslibpy expects:
message["status"] # <-- Expects it at top level
The ActionClient's result callback should receive the action result
without crashing. The handler should properly parse the action result
message from rosbridge and pass the result data to the user's callback
function.
Screenshots
System (please complete the following information):
- OS: Ubuntu 24.04
- Python version 3.12
- Python package manager pip
- roslibpy version: main branch (commit 1d549b7)
- rosbridge_suite version: ros2 branch
- ROS version: ROS2 Humble
Additional context
The bug occurs at line 166 in src/roslibpy/comm/comm.py where the handler
tries to access message["status"] for logging before verifying it
exists. The rosbridge protocol for ROS2 actions sends:
{
"op": "action_result",
"action": "/action_name",
"id": "send_action_goal:/action_name:1",
"status": 3,
"values": {...},
"result": true
}
Current workaround that users can apply:
from roslibpy.comm import comm
def fix(self, msg):
handlers = self._pending_action_requests.pop(msg["id"], None)
if handlers and msg.get("result"):
handlers[0]({"status": msg.get("status"), "values":
msg.get("values", {})})
elif handlers:
handlers[2]("Action failed")
comm.RosBridgeProtocol._handle_action_result = fix