Re: [ros-users] Throwing exceptions in services (Python vs. …

Forside
Vedhæftede filer:
Indlæg som e-mail
+ (text/plain)
+ issue3590.patch (text/x-patch)
Slet denne besked
Besvar denne besked
Skribent: User discussions
Dato:  
Til: User discussions
Emne: Re: [ros-users] Throwing exceptions in services (Python vs. C++)
I looked into the issue posted one month ago, that thrown exceptions in service-servers are not passed to the service-clients.
This is at least the case for roscpp - in rospy (and roslisp) it is implemented already.

After some "warm-up" with the respective code-parts I came up with a small patch (see attached - this is not meant to be committed!!!).
I have tested the following scenario:
- add_two_ints_server (c++, modified to throw a runtime-exception)
called by
- add_two_ints_client (py)

Usually the serialization of the response (generated in "serializeServiceResponse") contains the following content: ok-flag, msg-size, msg-payload.
But in order to make it compatible with rospy the response must contain only: ok-flag, msg-payload.

Before looking at the client part of the roscpp service handling (to also output the received error string) I would like to clarify the serialization format.
Is there any specification how a service response must look like (even in the case of "ok" being false)?
Is the current implementation of rospy/roslisl "correct" or should it be altered to also contain the message size?

Dirk



On 08.11.2011 17:31, Thibault Kruse wrote:
> I raised this a while ago here:
> https://code.ros.org/trac/ros/ticket/3590
> but i could not provide a patch myself.
>
> With a patch the ticket may get more attention.
>
> It should not be too difficult technically (I implemented it for roslisp as for
> rospy in https://code.ros.org/trac/ros/ticket/3594), but I found it too hard
> to dig into the roscpp code.
>
>
>
>
> On 11/08/2011 05:13 PM, Dirk Thomas wrote:
>> Hi,
>>
>> we are using ROS services implemented in Python as well as in C++.
>> We found one significant difference in both implementations (which makes debugging more difficult):
>> This is when a service throws an exception.
>>
>> In both languages a message is printed on the server's console.
>> In Python the string of the exception is also passed to the client.
>> But in C++ the exception is NOT passed to the client.
>>
>> Is there a technical reason why the C++-ServiceCallback does not pass the exception message?
>> If not could this be added?
>>
>> Regards,
>> Dirk

Index: clients/cpp/roscpp_serialization/include/ros/serialization.h
===================================================================
--- clients/cpp/roscpp_serialization/include/ros/serialization.h    (revision 15393)
+++ clients/cpp/roscpp_serialization/include/ros/serialization.h    (working copy)
@@ -833,6 +833,16 @@
     serialize(s, (uint32_t)m.num_bytes - 5);
     serialize(s, message);
   }
+  else if (!ok) // this is only to illustrate the diff to the already existing else block
+  {
+    uint32_t len = serializationLength(message);
+    m.num_bytes = len + 1;
+    m.buf.reset(new uint8_t[m.num_bytes]);
+
+    OStream s(m.buf.get(), (uint32_t)m.num_bytes);
+    serialize(s, (uint8_t)ok);
+    serialize(s, message);
+  }
   else
   {
     m.num_bytes = 5;
Index: clients/cpp/roscpp/src/libros/service_publication.cpp
===================================================================
--- clients/cpp/roscpp/src/libros/service_publication.cpp    (revision 15393)
+++ clients/cpp/roscpp/src/libros/service_publication.cpp    (working copy)
@@ -39,6 +39,8 @@


#include <boost/bind.hpp>

+#include <std_msgs/String.h>
+
namespace ros
{

@@ -126,7 +128,9 @@
     catch (std::exception& e)
     {
       ROS_ERROR("Exception thrown while processing service call: %s", e.what());
-      SerializedMessage res = serialization::serializeServiceResponse(false, 0);
+      std_msgs::String error_string;
+      error_string.data = e.what();
+      SerializedMessage res = serialization::serializeServiceResponse(false, error_string);
       link_->processResponse(false, res);
       return Invalid;
     }