I have created and attached a patch for issue
https://code.ros.org/trac/ros/ticket/3590
It currently does the following:
- for every std::exception already catched on the server it passes the e.what() to the client (as rospy and roslisp already do)
- output an error message on the client containing the exception string in case of server-side exceptions
One open question is if a new exception should be introduced (ServiceException similar to rospy)?
Then only error messages from ServiceException would be passed from server to client (other exceptions are handled without passing the error message).
And on the client the same exception-type could be (re-)thrown.
While this approach looks much cleaner it work break with the current behavior.
What is your opinion on the patch?
Would you vote to modify the patch to introduce a ServiceException as described above?
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)
@@ -835,11 +835,13 @@
}
else
{
- m.num_bytes = 5;
- m.buf.reset(new uint8_t[5]);
+ 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, (uint32_t)0);
+ serialize(s, message);
}
return m;
Index: clients/cpp/roscpp/include/ros/service_server_link.h
===================================================================
--- clients/cpp/roscpp/include/ros/service_server_link.h (revision 15393)
+++ clients/cpp/roscpp/include/ros/service_server_link.h (working copy)
@@ -70,6 +70,8 @@
bool success_;
bool call_finished_;
+
+ std::string exception_string_;
};
typedef boost::shared_ptr<CallInfo> CallInfoPtr;
typedef std::queue<CallInfoPtr> Q_CallInfo;
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;
}
Index: clients/cpp/roscpp/src/libros/service_server_link.cpp
===================================================================
--- clients/cpp/roscpp/src/libros/service_server_link.cpp (revision 15393)
+++ clients/cpp/roscpp/src/libros/service_server_link.cpp (working copy)
@@ -236,6 +236,10 @@
{
*current_call_->resp_ = SerializedMessage(buffer, size);
}
+ else
+ {
+ current_call_->exception_string_ = std::string(reinterpret_cast<char*>(buffer.get()), size);
+ }
}
callFinished();
@@ -363,6 +367,11 @@
info->call_finished_ = true;
+ if (info->exception_string_.length() > 0)
+ {
+ ROS_ERROR("Service call failed: service [%s] responded with an error: %s", service_name_.c_str(), info->exception_string_.c_str());
+ }
+
return info->success_;
}