Client waitForService response can be incorrect
Description
A ROS node implements a service but throw an exception when calling it.
This error is never thrown on rclnodejs side (C++ I guess) and the client.sendRequest never response.
- Library Version: 0.28.1
- ROS Version: Ros2 humble
- Platform / OS: Ubuntu 22
Steps To Reproduce
Inside our code base, we have a node named /bt_navigator_rclcpp_node. The issue is that we do not directly spin the node, but another node spinning it for us.
When calling ros2 param list /bt_navigator_rclcpp_node inside a terminal, the following exception is thrown:
Exception while calling service of node '/bt_navigator_rclcpp_node': None
Actual Behavior In my Node code, I use the following function in order to call the service:
private _callService(client: Client<ROS_CLIENT_TYPES>, request: ROS_REQUEST_TYPES, callback: (response?: unknown) => void): void {
const doesServiceExists = client.isServiceServerAvailable();
if (!doesServiceExists) {
callback(undefined);
this._destroyClient(client);
return;
}
client.waitForService(ROS_SUBSCRIBER_TIMEOUT_MS)
.then((isAvailable: boolean) => {
if (!isAvailable) {
callback(undefined);
this._destroyClient(client);
}
console.log('1. Calling: service', client.serviceName);
client.sendRequest(request, (response: unknown) => {
console.log('2. Response received: service', client.serviceName);
callback(response);
this._destroyClient(client);
});
});
}
The issue is that isServiceServerAvailable function returns true (which means that the list parameter service exists on this node, and which is the case) and waitForService also returns true (which means that the service is available right now, which is not the case as this service is buggy). Next, the first console log is properly printed, but the second one is never displayed. I also tried to catch any exception by surrounding the sendRequest method with a try catch. No error are thrown on rclnodejs side.
Expected Behavior
waitForService should returns false in case of unavailable service.
Hi @PierreSachot thanks for your detailed description and investigation, so your scenario is:
- A node named
bt_navigator_rclcpp_node, running the actual service. - The other node implemented by
rclnodejsrunning the code snippet shown in your comment. - Running
ros2 param list /bt_navigator_rclcpp_node, then get the exception.
If I understand correctly, isServiceServerAvailable() returns the service (under node bt_navigator_rclcpp_node) status of step 1, instead of the list parameter service, please also check with https://robotwebtools.github.io/rclnodejs/docs/0.28.0/Client.html
Sorry @minggangw I missed your answer.
Exactly, this is the proper steps to reproduce. The issue is related to waitForService and not isServiceServerAvailable. Did you manage to reproduce and/or correct it?
I see, I simply tried with client-example.js and the waitForService seems working as expected, can you please try it again using latest version of rclnodejs?
@minggangw Hi, thanks for your response.
I did try again using rlnodejs 0.27.4. I can confirm that the issue is still present.
We are facing it once again in another context:
- Create a first node
- Create an rclnodejs node
- Create a client to talk with the first node inside the rclnodejs node
- Send a first request: the response is received and everything works well
- Kill the first node
- Send a second request:
waitForServiceresponse is resolving and when sending a second request to the node, there is no response / no error catched.
Thanks a lot in advance, Pierre
@PierreSachot I will take a look later and get back to you.
Hi @PierreSachot I did some simple testing as
- ROS2 Jazzy + Ubuntu 24.04
- rclnodejs v1.2.0
- client-example.js + service-example.js
The screen recording:
Please help to check if the testing steps is what you described above, thanks!