diff --git a/rclcpp/include/rclcpp/exceptions/exceptions.hpp b/rclcpp/include/rclcpp/exceptions/exceptions.hpp index 524ccf73ea..bf67c50d6d 100644 --- a/rclcpp/include/rclcpp/exceptions/exceptions.hpp +++ b/rclcpp/include/rclcpp/exceptions/exceptions.hpp @@ -254,6 +254,23 @@ class InvalidParameterTypeException : public std::runtime_error {} }; +/// Thrown if user attempts to create an uninitialized statically typed parameter +/** + * (see https://github.com/ros2/rclcpp/issues/1691) + */ +class UninitializedStaticallyTypedParameterException : public std::runtime_error +{ +public: + /// Construct an instance. + /** + * \param[in] name the name of the parameter. + */ + RCLCPP_PUBLIC + explicit UninitializedStaticallyTypedParameterException(const std::string & name) + : std::runtime_error("Statically typed parameter '" + name + "' must be initialized.") + {} +}; + /// Thrown if parameter is already declared. class ParameterAlreadyDeclaredException : public std::runtime_error { diff --git a/rclcpp/include/rclcpp/node_impl.hpp b/rclcpp/include/rclcpp/node_impl.hpp index df6039cf49..46f54aa054 100644 --- a/rclcpp/include/rclcpp/node_impl.hpp +++ b/rclcpp/include/rclcpp/node_impl.hpp @@ -220,12 +220,16 @@ Node::declare_parameter( // get advantage of parameter value template magic to get // the correct rclcpp::ParameterType from ParameterT rclcpp::ParameterValue value{ParameterT{}}; - return this->declare_parameter( - name, - value.get_type(), - parameter_descriptor, - ignore_override - ).get(); + try { + return this->declare_parameter( + name, + value.get_type(), + parameter_descriptor, + ignore_override + ).get(); + } catch (const ParameterTypeException &) { + throw exceptions::UninitializedStaticallyTypedParameterException(name); + } } template diff --git a/rclcpp/test/rclcpp/test_node.cpp b/rclcpp/test/rclcpp/test_node.cpp index fc2f564c75..f3fb13119f 100644 --- a/rclcpp/test/rclcpp/test_node.cpp +++ b/rclcpp/test/rclcpp/test_node.cpp @@ -715,6 +715,12 @@ TEST_F(TestNode, declare_parameter_with_overrides) { "parameter_type_mismatch", rclcpp::ParameterType::PARAMETER_INTEGER);}, rclcpp::exceptions::InvalidParameterTypeException); } + { + // statically typed parameter must be initialized + EXPECT_THROW( + {node->declare_parameter("static_and_uninitialized");}, + rclcpp::exceptions::UninitializedStaticallyTypedParameterException); + } { // cannot pass an expected type and a descriptor with dynamic_typing=True rcl_interfaces::msg::ParameterDescriptor descriptor{};