Skip to content

Commit dae4660

Browse files
authored
Don't crash when type definition cannot be found (ros2#1350)
* Don't fail when type definition cannot be found Signed-off-by: Emerson Knapp <[email protected]>
1 parent 92fa887 commit dae4660

File tree

4 files changed

+46
-9
lines changed

4 files changed

+46
-9
lines changed

rosbag2_cpp/src/rosbag2_cpp/message_definitions/local_message_definition_source.cpp

+31-9
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414

1515
#include "rosbag2_cpp/message_definitions/local_message_definition_source.hpp"
1616

17-
#include <rcutils/logging_macros.h>
18-
1917
#include <fstream>
2018
#include <functional>
2119
#include <optional>
@@ -27,8 +25,28 @@
2725

2826
#include <ament_index_cpp/get_package_share_directory.hpp>
2927

28+
#include "rosbag2_cpp/logging.hpp"
29+
3030
namespace rosbag2_cpp
3131
{
32+
33+
/// A type name did not match expectations, so a definition could not be looked for.
34+
class TypenameNotUnderstoodError : public std::exception
35+
{
36+
private:
37+
std::string name_;
38+
39+
public:
40+
explicit TypenameNotUnderstoodError(std::string name)
41+
: name_(std::move(name))
42+
{}
43+
44+
const char * what() const noexcept override
45+
{
46+
return name_.c_str();
47+
}
48+
};
49+
3250
// Match datatype names (foo_msgs/Bar or foo_msgs/msg/Bar)
3351
static const std::regex PACKAGE_TYPENAME_REGEX{R"(^([a-zA-Z0-9_]+)/(?:msg/)?([a-zA-Z0-9_]+)$)"};
3452

@@ -144,7 +162,7 @@ const LocalMessageDefinitionSource::MessageSpec & LocalMessageDefinitionSource::
144162
std::smatch match;
145163
const auto topic_type = definition_identifier.topic_type();
146164
if (!std::regex_match(topic_type, match, PACKAGE_TYPENAME_REGEX)) {
147-
throw std::invalid_argument("Invalid topic_type: " + topic_type);
165+
throw TypenameNotUnderstoodError(topic_type);
148166
}
149167
std::string package = match[1];
150168
std::string share_dir = ament_index_cpp::get_package_share_directory(package);
@@ -195,26 +213,30 @@ rosbag2_storage::MessageDefinition LocalMessageDefinitionSource::get_full_text(
195213
try {
196214
result = append_recursive(DefinitionIdentifier(root_topic_type, format), max_recursion_depth);
197215
} catch (const DefinitionNotFoundError & err) {
198-
// log that we've fallen back
199-
RCUTILS_LOG_WARN_NAMED(
200-
"rosbag2_cpp", "no .msg definition for %s, falling back to IDL",
201-
err.what());
216+
ROSBAG2_CPP_LOG_WARN("No .msg definition for %s, falling back to IDL", err.what());
202217
format = Format::IDL;
203218
DefinitionIdentifier root_definition_identifier(root_topic_type, format);
204219
result = (delimiter(root_definition_identifier) +
205220
append_recursive(root_definition_identifier, max_recursion_depth));
221+
} catch (const TypenameNotUnderstoodError & err) {
222+
ROSBAG2_CPP_LOG_ERROR(
223+
"Message type name '%s' not understood by type definition search, "
224+
"definition will be left empty in bag.", err.what());
225+
format = Format::UNKNOWN;
206226
}
207227
rosbag2_storage::MessageDefinition out;
208228
switch (format) {
209229
case Format::UNKNOWN:
210-
throw std::runtime_error{"could not determine format of message definition for type " +
211-
root_topic_type};
230+
out.encoding = "unknown";
231+
break;
212232
case Format::MSG:
213233
out.encoding = "ros2msg";
214234
break;
215235
case Format::IDL:
216236
out.encoding = "ros2idl";
217237
break;
238+
default:
239+
throw std::runtime_error("switch is not exhaustive");
218240
}
219241
out.encoded_message_definition = result;
220242
out.topic_type = root_topic_type;

rosbag2_cpp/test/rosbag2_cpp/test_local_message_definition_source.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,14 @@ TEST(test_local_message_definition_source, can_resolve_msg_with_idl_deps)
125125
" };\n"
126126
"};\n");
127127
}
128+
129+
TEST(test_local_message_definition_source, no_crash_on_bad_name)
130+
{
131+
LocalMessageDefinitionSource source;
132+
rosbag2_storage::MessageDefinition result;
133+
ASSERT_NO_THROW(
134+
{
135+
result = source.get_full_text("rosbag2_test_msgdefs/srv/BasicSrv_Request");
136+
});
137+
ASSERT_EQ(result.encoding, "unknown");
138+
}

rosbag2_test_msgdefs/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ rosidl_generate_interfaces(${PROJECT_NAME}
1414
"msg/BasicMsg.msg"
1515
"msg/ComplexMsg.msg"
1616
"msg/ComplexMsgDependsOnIdl.msg"
17+
"srv/BasicSrv.srv"
1718
ADD_LINTER_TESTS
1819
)
1920

rosbag2_test_msgdefs/srv/BasicSrv.srv

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
string req
2+
---
3+
string resp

0 commit comments

Comments
 (0)